diff --git a/.build_adios2_for_ci.sh b/.build_adios2_for_ci.sh new file mode 100755 index 0000000000..c6d4178884 --- /dev/null +++ b/.build_adios2_for_ci.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +set -e + +if test $BUILD_ADIOS2 ; then + if [[ ! -d $HOME/local/adios/include/adios2.h ]] || test $1 ; then + echo "****************************************" + echo "Building ADIOS2" + echo "****************************************" + + branch=${1:-release_29} + if [ ! -d adios2 ]; then + git clone -b $branch https://github.com/ornladios/ADIOS2.git adios2 --depth=1 + fi + + pushd adios2 + rm -rf build + mkdir -p build + pushd build + + cmake .. \ + -DCMAKE_INSTALL_PREFIX=$HOME/local \ + -DADIOS2_USE_MPI=ON \ + -DADIOS2_USE_Fortran=OFF \ + -DADIOS2_USE_Python=OFF \ + -DADIOS2_BUILD_EXAMPLES=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ + -DBUILD_TESTING=OFF \ + -DADIOS2_USE_SST=OFF \ + -DADIOS2_USE_MGARD=OFF \ + -DADIOS2_USE_HDF5=OFF \ + -DADIOS2_USE_BZip2=OFF \ + -DADIOS2_USE_Blosc2=OFF \ + -DADIOS2_USE_SZ=OFF \ + -DADIOS2_USE_ZFP=OFF \ + -DADIOS2_USE_DAOS=OFF \ + -DADIOS2_USE_UCX=OFF \ + -DADIOS2_USE_LIBPRESSIO=OFF \ + -DADIOS2_USE_Sodium=OFF \ + -DADIOS2_USE_ZeroMQ=OFF \ + -DADIOS2_USE_MHS=OFF \ + -DADIOS2_USE_DataMan=OFF + + make -j 4 && make install + popd + + echo "****************************************" + echo " Finished building ADIOS2" + echo "****************************************" + + else + + echo "****************************************" + echo " ADIOS2 already installed" + echo "****************************************" + fi +else + echo "****************************************" + echo " ADIOS2 not requested" + echo "****************************************" +fi diff --git a/.ci_fedora.sh b/.ci_fedora.sh index 0774000b9c..b8805abb15 100755 --- a/.ci_fedora.sh +++ b/.ci_fedora.sh @@ -50,12 +50,13 @@ then cp -a /tmp/BOUT-dev /home/test/ chown -R test /home/test chmod u+rwX /home/test -R - sudo -u test ${0/\/tmp/\/home\/test} $mpi + su - test -c "${0/\/tmp/\/home\/test} $mpi" ## If we are called as normal user, run test else . /etc/profile.d/modules.sh module load mpi/${1}-x86_64 export OMPI_MCA_rmaps_base_oversubscribe=yes + export PRTE_MCA_rmaps_default_mapping_policy=:oversubscribe export TRAVIS=true export FLEXIBLAS=NETLIB cd diff --git a/.clang-format b/.clang-format index f51c5bde87..a80c59bddd 100644 --- a/.clang-format +++ b/.clang-format @@ -109,6 +109,8 @@ SpacesInParentheses: false SpacesInSquareBrackets: false StatementMacros: - BOUT_OMP + - BOUT_OMP_PERF + - BOUT_OMP_SAFE Standard: c++14 TabWidth: 8 UseTab: Never diff --git a/.clang-tidy b/.clang-tidy index 7a1c58af80..0117c20e42 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,363 +1,41 @@ --- -Checks: 'clang-diagnostic-*,clang-analyzer-*,-*,performance-*,readability-*,bugprone-*,clang-analyzer-*,cppcoreguidelines-*,mpi-*,misc-*,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-misc-non-private-member-variables-in-classes,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-type-vararg,-clang-analyzer-optin.mpi*,-bugprone-exception-escape,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-readability-function-cognitive-complexity' +Checks: 'clang-diagnostic-*,clang-analyzer-*,performance-*,readability-*,bugprone-*,clang-analyzer-*,cppcoreguidelines-*,mpi-*,misc-*,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-misc-non-private-member-variables-in-classes,-clang-analyzer-optin.mpi*,-bugprone-exception-escape,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-readability-function-cognitive-complexity,-misc-no-recursion,-bugprone-easily-swappable-parameters' WarningsAsErrors: '' HeaderFilterRegex: '' -AnalyzeTemporaryDtors: false FormatStyle: file CheckOptions: - - key: performance-unnecessary-copy-initialization.ExcludedContainerTypes - value: '' - - key: readability-suspicious-call-argument.PrefixSimilarAbove - value: '30' - - key: modernize-replace-auto-ptr.IncludeStyle - value: llvm - - key: cppcoreguidelines-no-malloc.Reallocations - value: '::realloc' - - key: cppcoreguidelines-owning-memory.LegacyResourceConsumers - value: '::free;::realloc;::freopen;::fclose' - - key: readability-static-accessed-through-instance.NameSpecifierNestingThreshold - value: '3' - - key: readability-function-size.VariableThreshold - value: '4294967295' - - key: bugprone-narrowing-conversions.PedanticMode - value: 'false' - - key: bugprone-unused-return-value.CheckedFunctions - value: '::std::async;::std::launder;::std::remove;::std::remove_if;::std::unique;::std::unique_ptr::release;::std::basic_string::empty;::std::vector::empty;::std::back_inserter;::std::distance;::std::find;::std::find_if;::std::inserter;::std::lower_bound;::std::make_pair;::std::map::count;::std::map::find;::std::map::lower_bound;::std::multimap::equal_range;::std::multimap::upper_bound;::std::set::count;::std::set::find;::std::setfill;::std::setprecision;::std::setw;::std::upper_bound;::std::vector::at;::bsearch;::ferror;::feof;::isalnum;::isalpha;::isblank;::iscntrl;::isdigit;::isgraph;::islower;::isprint;::ispunct;::isspace;::isupper;::iswalnum;::iswprint;::iswspace;::isxdigit;::memchr;::memcmp;::strcmp;::strcoll;::strncmp;::strpbrk;::strrchr;::strspn;::strstr;::wcscmp;::access;::bind;::connect;::difftime;::dlsym;::fnmatch;::getaddrinfo;::getopt;::htonl;::htons;::iconv_open;::inet_addr;::isascii;::isatty;::mmap;::newlocale;::openat;::pathconf;::pthread_equal;::pthread_getspecific;::pthread_mutex_trylock;::readdir;::readlink;::recvmsg;::regexec;::scandir;::semget;::setjmp;::shm_open;::shmget;::sigismember;::strcasecmp;::strsignal;::ttyname' - - key: performance-move-const-arg.CheckTriviallyCopyableMove - value: 'true' - - key: cert-dcl16-c.NewSuffixes - value: 'L;LL;LU;LLU' - - key: bugprone-reserved-identifier.Invert - value: 'false' - - key: readability-identifier-naming.GetConfigPerFile - value: 'true' - - key: bugprone-narrowing-conversions.WarnOnFloatingPointNarrowingConversion - value: 'true' - - key: readability-inconsistent-declaration-parameter-name.Strict - value: 'false' - - key: cppcoreguidelines-macro-usage.CheckCapsOnly - value: 'false' - - key: readability-suspicious-call-argument.DiceDissimilarBelow - value: '60' - - key: readability-function-size.NestingThreshold - value: '4294967295' - - key: cppcoreguidelines-narrowing-conversions.IgnoreConversionFromTypes - value: '' - - key: readability-function-size.ParameterThreshold - value: '4294967295' - - key: readability-suspicious-call-argument.Equality - value: 'true' - - key: readability-function-cognitive-complexity.IgnoreMacros - value: 'false' - - key: cert-str34-c.DiagnoseSignedUnsignedCharComparisons - value: 'false' - - key: misc-uniqueptr-reset-release.IncludeStyle - value: llvm - - key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison - value: 'false' - - key: bugprone-narrowing-conversions.WarnWithinTemplateInstantiation - value: 'false' - - key: readability-redundant-smartptr-get.IgnoreMacros - value: 'true' - - key: cppcoreguidelines-explicit-virtual-functions.AllowOverrideAndFinal - value: 'false' - - key: readability-identifier-naming.AggressiveDependentMemberLookup - value: 'false' - - key: bugprone-easily-swappable-parameters.QualifiersMix - value: 'false' - - key: bugprone-suspicious-string-compare.WarnOnImplicitComparison - value: 'true' - - key: bugprone-argument-comment.CommentNullPtrs - value: '0' - - key: cppcoreguidelines-owning-memory.LegacyResourceProducers - value: '::malloc;::aligned_alloc;::realloc;::calloc;::fopen;::freopen;::tmpfile' - - key: bugprone-easily-swappable-parameters.SuppressParametersUsedTogether - value: 'true' - - key: bugprone-argument-comment.StrictMode - value: '0' - - key: cppcoreguidelines-init-variables.IncludeStyle - value: llvm - - key: cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion - value: 'true' - - key: bugprone-easily-swappable-parameters.NamePrefixSuffixSilenceDissimilarityTreshold - value: '1' - - key: bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField - value: 'true' - - key: google-readability-namespace-comments.ShortNamespaceLines - value: '10' - - key: readability-suspicious-call-argument.JaroWinklerDissimilarBelow - value: '75' - - key: bugprone-suspicious-string-compare.StringCompareLikeFunctions - value: '' - - key: misc-definitions-in-headers.HeaderFileExtensions - value: ';h;hh;hpp;hxx' - - key: readability-suspicious-call-argument.Suffix - value: 'true' - - key: cppcoreguidelines-narrowing-conversions.WarnOnIntegerNarrowingConversion - value: 'true' - - key: readability-suspicious-call-argument.SuffixSimilarAbove - value: '30' - - key: bugprone-easily-swappable-parameters.IgnoredParameterNames - value: '"";iterator;Iterator;begin;Begin;end;End;first;First;last;Last;lhs;LHS;rhs;RHS' - - key: cppcoreguidelines-prefer-member-initializer.UseAssignment - value: 'false' - - key: performance-type-promotion-in-math-fn.IncludeStyle - value: llvm - - key: cppcoreguidelines-explicit-virtual-functions.FinalSpelling - value: final - - key: readability-function-cognitive-complexity.DescribeBasicIncrements - value: 'true' - - key: readability-suspicious-call-argument.MinimumIdentifierNameLength - value: '3' - - key: bugprone-narrowing-conversions.WarnOnIntegerNarrowingConversion - value: 'true' - - key: modernize-loop-convert.NamingStyle - value: CamelCase - - key: bugprone-suspicious-include.ImplementationFileExtensions - value: 'c;cc;cpp;cxx' - - key: cppcoreguidelines-pro-type-member-init.UseAssignment - value: 'false' - - key: bugprone-suspicious-missing-comma.SizeThreshold - value: '5' - - key: bugprone-suspicious-include.HeaderFileExtensions - value: ';h;hh;hpp;hxx' - - key: performance-no-automatic-move.AllowedTypes - value: '' - - key: readability-suspicious-call-argument.SubstringDissimilarBelow - value: '40' - - key: bugprone-argument-comment.CommentIntegerLiterals - value: '0' - - key: performance-for-range-copy.WarnOnAllAutoCopies - value: 'false' - - key: readability-inconsistent-declaration-parameter-name.IgnoreMacros - value: 'true' - - key: readability-identifier-naming.IgnoreFailedSplit - value: 'false' - - key: modernize-pass-by-value.IncludeStyle - value: llvm - - key: readability-qualified-auto.AddConstToQualified - value: 'true' - - key: bugprone-sizeof-expression.WarnOnSizeOfThis - value: 'true' - - key: bugprone-string-constructor.WarnOnLargeLength - value: 'true' - - key: bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit - value: '16' - - key: readability-simplify-boolean-expr.ChainedConditionalReturn - value: 'false' - - key: bugprone-argument-comment.CommentFloatLiterals - value: '0' - - key: cppcoreguidelines-explicit-virtual-functions.OverrideSpelling - value: override - - key: bugprone-argument-comment.CommentCharacterLiterals - value: '0' - - key: readability-else-after-return.WarnOnConditionVariables - value: 'true' - - key: readability-uppercase-literal-suffix.IgnoreMacros - value: 'true' - - key: modernize-use-nullptr.NullMacros - value: 'NULL' - - key: readability-suspicious-call-argument.SuffixDissimilarBelow - value: '25' - - key: bugprone-dynamic-static-initializers.HeaderFileExtensions - value: ';h;hh;hpp;hxx' - - key: bugprone-suspicious-enum-usage.StrictMode - value: 'false' - - key: performance-unnecessary-copy-initialization.AllowedTypes - value: '' - - key: readability-suspicious-call-argument.LevenshteinSimilarAbove - value: '66' - - key: bugprone-suspicious-missing-comma.MaxConcatenatedTokens - value: '5' - - key: cppcoreguidelines-narrowing-conversions.PedanticMode - value: 'false' - - key: readability-suspicious-call-argument.Levenshtein - value: 'true' - - key: bugprone-implicit-widening-of-multiplication-result.UseCXXHeadersInCppSources - value: 'true' - - key: readability-suspicious-call-argument.JaroWinkler - value: 'true' - - key: misc-throw-by-value-catch-by-reference.CheckThrowTemporaries - value: 'true' - - key: bugprone-string-constructor.LargeLengthThreshold - value: '8388608' - - key: readability-suspicious-call-argument.Prefix - value: 'true' - - key: readability-simplify-boolean-expr.ChainedConditionalAssignment - value: 'false' - - key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions - value: 'false' - - key: cppcoreguidelines-macro-usage.AllowedRegexp - value: '^DEBUG_*' - - key: bugprone-implicit-widening-of-multiplication-result.UseCXXStaticCastsInCppSources - value: 'true' - - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField - value: 'false' - - key: bugprone-exception-escape.FunctionsThatShouldNotThrow - value: '' - - key: bugprone-signed-char-misuse.CharTypdefsToIgnore - value: '' - - key: performance-inefficient-vector-operation.EnableProto - value: 'false' - - key: modernize-loop-convert.MaxCopySize - value: '16' - - key: readability-suspicious-call-argument.PrefixDissimilarBelow - value: '25' - - key: readability-function-size.LineThreshold - value: '4294967295' - - key: bugprone-easily-swappable-parameters.MinimumLength - value: '2' - - key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader - value: '' - - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors - value: 'true' - - key: performance-for-range-copy.AllowedTypes - value: '' - - key: bugprone-argument-comment.CommentStringLiterals - value: '0' - - key: bugprone-sizeof-expression.WarnOnSizeOfConstant - value: 'true' - - key: readability-redundant-string-init.StringNames - value: '::std::basic_string_view;::std::basic_string' - - key: bugprone-argument-comment.CommentBoolLiterals - value: '0' - - key: readability-braces-around-statements.ShortStatementLines - value: '0' - - key: bugprone-argument-comment.CommentUserDefinedLiterals - value: '0' - - key: bugprone-not-null-terminated-result.WantToUseSafeFunctions - value: 'true' - - key: readability-suspicious-call-argument.LevenshteinDissimilarBelow - value: '50' - - key: readability-redundant-declaration.IgnoreMacros - value: 'true' - - key: performance-inefficient-string-concatenation.StrictMode - value: 'false' - - key: bugprone-easily-swappable-parameters.IgnoredParameterTypeSuffixes - value: 'bool;Bool;_Bool;it;It;iterator;Iterator;inputit;InputIt;forwardit;FowardIt;bidirit;BidirIt;constiterator;const_iterator;Const_Iterator;Constiterator;ConstIterator;RandomIt;randomit;random_iterator;ReverseIt;reverse_iterator;reverse_const_iterator;ConstReverseIterator;Const_Reverse_Iterator;const_reverse_iterator;Constreverseiterator;constreverseiterator' - - key: google-readability-braces-around-statements.ShortStatementLines - value: '1' - - key: bugprone-reserved-identifier.AllowedIdentifiers - value: '' - - key: cppcoreguidelines-pro-type-member-init.IgnoreArrays - value: 'false' - - key: readability-else-after-return.WarnOnUnfixable - value: 'true' - - key: readability-implicit-bool-conversion.AllowPointerConditions - value: 'false' - - key: readability-suspicious-call-argument.SubstringSimilarAbove - value: '50' - - key: bugprone-signal-handler.AsyncSafeFunctionSet - value: POSIX - - key: cppcoreguidelines-pro-bounds-constant-array-index.IncludeStyle - value: llvm - - key: readability-suspicious-call-argument.Substring - value: 'true' - - key: bugprone-easily-swappable-parameters.ModelImplicitConversions - value: 'true' - - key: cppcoreguidelines-macro-usage.IgnoreCommandLineMacros - value: 'true' - - key: cppcoreguidelines-narrowing-conversions.WarnWithinTemplateInstantiation - value: 'false' - - key: readability-suspicious-call-argument.Abbreviations - value: 'arr=array;cnt=count;idx=index;src=source;stmt=statement;cpy=copy;dest=destination;dist=distancedst=distance;ptr=pointer;wdth=width;str=string;ln=line;srv=server;attr=attribute;ref=reference;buf=buffer;col=column;nr=number;vec=vector;len=length;elem=element;val=value;i=index;var=variable;hght=height;cl=client;num=number;pos=position;lst=list;addr=address' - - key: cppcoreguidelines-narrowing-conversions.WarnOnEquivalentBitWidth - value: 'true' - - key: bugprone-misplaced-widening-cast.CheckImplicitCasts - value: 'false' - - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnorePublicMemberVariables - value: 'false' - - key: modernize-loop-convert.MinConfidence - value: reasonable - - key: performance-unnecessary-value-param.AllowedTypes - value: '' - - key: readability-uniqueptr-delete-release.PreferResetCall - value: 'false' - - key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctionsWhenCopyIsDeleted - value: 'false' - - key: misc-definitions-in-headers.UseHeaderFileExtension - value: 'true' - - key: google-readability-namespace-comments.SpacesBeforeComments - value: '2' - - key: readability-function-cognitive-complexity.Threshold - value: '25' - - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic - value: 'true' - - key: readability-uppercase-literal-suffix.NewSuffixes - value: '' - - key: bugprone-suspicious-missing-comma.RatioThreshold - value: '0.200000' - - key: bugprone-argument-comment.IgnoreSingleArgument - value: '0' - - key: bugprone-narrowing-conversions.WarnOnEquivalentBitWidth - value: 'true' - - key: cppcoreguidelines-no-malloc.Allocations - value: '::malloc;::calloc' - - key: performance-faster-string-find.StringLikeClasses - value: '::std::basic_string;::std::basic_string_view' - - key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression - value: 'false' - - key: bugprone-assert-side-effect.CheckFunctionCalls - value: 'false' - - key: bugprone-string-constructor.StringNames - value: '::std::basic_string;::std::basic_string_view' - - key: bugprone-narrowing-conversions.IgnoreConversionFromTypes - value: '' - - key: readability-function-size.BranchThreshold - value: '4294967295' - - key: bugprone-assert-side-effect.AssertMacros - value: assert,NSAssert,NSCAssert - - key: readability-function-size.StatementThreshold - value: '800' - - key: llvm-qualified-auto.AddConstToQualified - value: 'false' - - key: bugprone-signed-char-misuse.DiagnoseSignedUnsignedCharComparisons - value: 'true' - - key: readability-identifier-naming.IgnoreMainLikeFunctions - value: 'false' - - key: bugprone-exception-escape.IgnoredExceptions - value: '' - - key: readability-implicit-bool-conversion.AllowIntegerConditions - value: 'false' - - key: google-readability-function-size.StatementThreshold - value: '800' - - key: llvm-else-after-return.WarnOnConditionVariables - value: 'false' - - key: cppcoreguidelines-init-variables.MathHeader - value: '' - - key: bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant - value: 'true' - - key: bugprone-reserved-identifier.AggressiveDependentMemberLookup - value: 'false' - - key: readability-suspicious-call-argument.DiceSimilarAbove - value: '70' - - key: readability-suspicious-call-argument.Dice - value: 'true' - - key: readability-suspicious-call-argument.Abbreviation + + # Allow some common short names + - key: readability-identifier-length.IgnoredVariableNames + value: '^[dn]?[xyz]$' + - key: readability-identifier-length.IgnoredParameterNames + value: '^[dfijknxyz][01xyz]?$' + - key: readability-identifier-length.IgnoredLoopCounterNames + value: '^[ijkxyz_]$' + + # Don't expand macros when simplifying boolean expressions, + # otherwise this breaks `ASSERT` macros! + - key: readability-simplify-boolean-expr.IgnoreMacros value: 'true' - - key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor - value: 'false' - - key: misc-throw-by-value-catch-by-reference.WarnOnLargeObjects - value: 'false' - - key: cppcoreguidelines-no-malloc.Deallocations - value: '::free' - - key: performance-inefficient-vector-operation.VectorLikeClasses - value: '::std::vector' - - key: bugprone-dangling-handle.HandleClasses - value: 'std::basic_string_view;std::experimental::basic_string_view' - - key: bugprone-implicit-widening-of-multiplication-result.IncludeStyle - value: llvm - - key: misc-unused-parameters.StrictMode - value: 'false' - - key: performance-unnecessary-value-param.IncludeStyle - value: llvm - - key: readability-suspicious-call-argument.JaroWinklerSimilarAbove - value: '85' - - key: readability-redundant-member-init.IgnoreBaseInCopyConstructors - value: 'false' - - key: llvm-else-after-return.WarnOnUnfixable - value: 'false' - - key: readability-simplify-subscript-expr.Types - value: '::std::basic_string;::std::basic_string_view;::std::vector;::std::array' -... +--- + +Disabled checks and reasons: + +These are all basically unavoidable in HPC numeric code: +-readability-magic-numbers +-cppcoreguidelines-avoid-magic-numbers +-cppcoreguidelines-pro-bounds-pointer-arithmetic +-readability-function-cognitive-complexity +-bugprone-easily-swappable-parameters + +This doesn't work very well: +-clang-analyzer-optin.mpi* + +This is a suggestion, and is perfectly fine: +-misc-no-recursion + +Expensive (and noisy, because we let exceptions escape from `main`): +-bugprone-exception-escape +TODO: This would be good to fix and re-enable: +-misc-non-private-member-variables-in-classes diff --git a/.github/workflows/clang-tidy-review.yml b/.github/workflows/clang-tidy-review.yml index d546ce3af2..f50d5aeff7 100644 --- a/.github/workflows/clang-tidy-review.yml +++ b/.github/workflows/clang-tidy-review.yml @@ -32,7 +32,7 @@ jobs: # the unit tests until they're fixed or ignored upstream exclude: "tests/unit/*cxx" cmake_command: | - pip install cmake && \ + pip install --break-system-packages cmake && \ cmake --version && \ git config --global --add safe.directory "$GITHUB_WORKSPACE" && \ cmake . -B build -DBUILD_SHARED_LIBS=ON \ diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6aaedb5804..bdaeb3dc4f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,6 +28,7 @@ jobs: OMP_NUM_THREADS: ${{ matrix.config.omp_num_threads }} PYTHONPATH: ${{ github.workspace }}/tools/pylib OMPI_MCA_rmaps_base_oversubscribe: yes + PRTE_MCA_rmaps_default_mapping_policy: ":oversubscribe" MPIRUN: mpiexec -np strategy: fail-fast: true @@ -38,7 +39,7 @@ jobs: is_cron: - ${{ github.event_name == 'cron' }} config: - - name: "CMake, PETSc unreleased" + - name: "CMake, PETSc unreleased, ADIOS2" os: ubuntu-20.04 cmake_options: "-DBUILD_SHARED_LIBS=ON -DBOUT_ENABLE_METRIC_3D=ON @@ -46,12 +47,15 @@ jobs: -DBOUT_USE_PETSC=ON -DBOUT_USE_SLEPC=ON -DBOUT_USE_SUNDIALS=ON + -DBOUT_USE_ADIOS2=ON -DBOUT_ENABLE_PYTHON=ON + -DADIOS2_ROOT=/home/runner/local/adios2 -DSUNDIALS_ROOT=/home/runner/local -DPETSC_DIR=/home/runner/local/petsc -DSLEPC_DIR=/home/runner/local/slepc" build_petsc: -petsc-main build_petsc_branch: main + build_adios2: true on_cron: true - name: "Default options, Ubuntu 20.04" @@ -185,9 +189,8 @@ jobs: - name: Install pip packages run: | - ./.pip_install_for_ci.sh 'cython~=0.29' 'netcdf4~=1.5' 'sympy~=1.5' 'gcovr' 'cmake' zoidberg fastcov - # Add the pip install location to the runner's PATH - echo ~/.local/bin >> $GITHUB_PATH + python -m pip install --upgrade pip setuptools + python -m pip install -r requirements.txt - name: Cache SUNDIALS build uses: actions/cache@v3 @@ -201,6 +204,9 @@ jobs: - name: Build PETSc run: BUILD_PETSC=${{ matrix.config.build_petsc }} ./.build_petsc_for_ci.sh ${{ matrix.config.build_petsc_branch }} + - name: Build ADIOS2 + run: BUILD_ADIOS2=${{ matrix.config.build_adios2 }} ./.build_adios2_for_ci.sh + - name: Build BOUT++ run: UNIT_ONLY=${{ matrix.config.unit_only }} ./.ci_with_cmake.sh ${{ matrix.config.cmake_options }} @@ -234,3 +240,30 @@ jobs: shell: bash env: TRAVIS_BUILD_DIR: ${{ github.workspace }} + CUDA: + timeout-minutes: 60 + runs-on: ubuntu-latest + container: ghcr.io/ggeorgakoudis/boutdev-cuda:latest + + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build minimal CUDA 12.2 @ GCC9.4.0 @ Ubuntu 20.04 + run: | + . /spack/share/spack/setup-env.sh + spack env activate -p /spack-env + git config --global --add safe.directory $GITHUB_WORKSPACE + rm -rf build + cmake -S $GITHUB_WORKSPACE -B build \ + -DCMAKE_C_COMPILER=gcc \ + -DCMAKE_CXX_COMPILER=g++ \ + -DBOUT_ENABLE_RAJA=on \ + -DBOUT_ENABLE_UMPIRE=on \ + -DBOUT_ENABLE_CUDA=on \ + -DCMAKE_CUDA_ARCHITECTURES=80 \ + -DCUDA_ARCH=compute_80,code=sm_80 \ + -DBOUT_ENABLE_WARNINGS=off \ + -DBOUT_USE_SYSTEM_FMT=on + cd build + make -j 4 diff --git a/.gitignore b/.gitignore index 7ddf9526ab..934da1c0de 100644 --- a/.gitignore +++ b/.gitignore @@ -85,3 +85,5 @@ coverage/ /_version.txt /BOUT++-v*.tar.gz /BOUT++-v*.tar.xz +/CMakeCache.txt +/CMakeFiles/cmake.check_cache diff --git a/.pip_install_for_ci.sh b/.pip_install_for_ci.sh deleted file mode 100755 index 4a5258cc2d..0000000000 --- a/.pip_install_for_ci.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -set -e - -export PATH=${HOME}/.local/bin:${PATH} -pip3 install --user --upgrade pip~=20.0 setuptools~=46.1 -pip3 install --user --upgrade scipy~=1.4 numpy~=1.18 natsort~=8.1.0 -for package in $@ -do - if test $package == "cython" - then - # fast install Cython - pip3 install --user Cython --install-option="--no-cython-compile" - elif test $package == "something_else" - then - pip3 install what_we_need - else - pip3 install --user $package - fi -done diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d20a10f78..d71dc470e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,16 @@ # Changelog -## [v5.1.0](https://github.com/boutproject/BOUT-dev/tree/v5.1.0 +## [v6.0.0](https://github.com/boutproject/BOUT-dev/tree/next) +[Full Changelog](https://github.com/boutproject/BOUT-dev/compare/v5.1.0...next) +### Breaking changes + +- The autotools `./configure` build system has been removed +- Parsing of booleans has changed [\#2828][https://github.com/boutproject/BOUT-dev/pull/2828] ([bendudson][https://github.com/bendudson]). + See the [manual page](https://bout-dev.readthedocs.io/en/stable/user_docs/bout_options.html#boolean-expressions) for details. + + +## [v5.1.0](https://github.com/boutproject/BOUT-dev/tree/v5.1.0) [Full Changelog](https://github.com/boutproject/BOUT-dev/compare/v5.0.0...v5.1.0) - Update RELEASE_HOWTO.md [\#2741][https://github.com/boutproject/BOUT-dev/pull/2741] ([dschwoerer][https://github.com/dschwoerer]) @@ -44,8 +53,8 @@ - Merge v5 into next - resolve conflicts [\#2658][https://github.com/boutproject/BOUT-dev/pull/2658] ([dschwoerer][https://github.com/dschwoerer]) - Update bundled boututils and boutdata [\#2657][https://github.com/boutproject/BOUT-dev/pull/2657] ([dschwoerer][https://github.com/dschwoerer]) -## [v5.0.0](https://github.com/boutproject/BOUT-dev/tree/next) -[Full Changelog](https://github.com/boutproject/BOUT-dev/compare/v4.3.2...next) +## [v5.0.0](https://github.com/boutproject/BOUT-dev/tree/v5.0.0) +[Full Changelog](https://github.com/boutproject/BOUT-dev/compare/v4.3.2...v5.0.0) ### Breaking changes diff --git a/CMakeLists.txt b/CMakeLists.txt index 2db9b79528..f57a78a14a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,7 @@ function(bout_update_submodules) endfunction() set(BOUT_SOURCES + ./include/bout/adios_object.hxx ./include/bout/array.hxx ./include/bout/assert.hxx ./include/bout/boundary_factory.hxx @@ -114,7 +115,6 @@ set(BOUT_SOURCES ./include/bout/field_factory.hxx ./include/bout/fieldgroup.hxx ./include/bout/fieldperp.hxx - ./include/bout/format.hxx ./include/bout/fv_ops.hxx ./include/bout/generic_factory.hxx ./include/bout/globalfield.hxx @@ -146,7 +146,7 @@ set(BOUT_SOURCES ./include/bout/openmpwrap.hxx ./include/bout/operatorstencil.hxx ./include/bout/options.hxx - ./include/bout/options_netcdf.hxx + ./include/bout/options_io.hxx ./include/bout/optionsreader.hxx ./include/bout/output.hxx ./include/bout/output_bout_types.hxx @@ -325,6 +325,7 @@ set(BOUT_SOURCES ./src/solver/impls/split-rk/split-rk.cxx ./src/solver/impls/split-rk/split-rk.hxx ./src/solver/solver.cxx + ./src/sys/adios_object.cxx ./src/sys/bout_types.cxx ./src/sys/boutcomm.cxx ./src/sys/boutexception.cxx @@ -338,7 +339,11 @@ set(BOUT_SOURCES ./src/sys/options/optionparser.hxx ./src/sys/options/options_ini.cxx ./src/sys/options/options_ini.hxx + ./src/sys/options/options_io.cxx ./src/sys/options/options_netcdf.cxx + ./src/sys/options/options_netcdf.hxx + ./src/sys/options/options_adios.cxx + ./src/sys/options/options_adios.hxx ./src/sys/optionsreader.cxx ./src/sys/output.cxx ./src/sys/petsclib.cxx @@ -361,7 +366,7 @@ else() set(BOUT_GENERATE_FIELDOPS_DEFAULT OFF) endif() -execute_process(COMMAND ${Python3_EXECUTABLE} -c "import zoidberg" +execute_process(COMMAND ${Python3_EXECUTABLE} -c "import importlib.util ; import sys; sys.exit(importlib.util.find_spec(\"zoidberg\") is None)" RESULT_VARIABLE zoidberg_FOUND) if (zoidberg_FOUND EQUAL 0) set(zoidberg_FOUND ON) @@ -462,9 +467,9 @@ set_target_properties(bout++ PROPERTIES # Set some variables for the bout-config script set(CONFIG_LDFLAGS "${CONFIG_LDFLAGS} -L\$BOUT_LIB_PATH -lbout++") set(BOUT_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/include") -set(CONFIG_CFLAGS "${CONFIG_CFLAGS} -I\${BOUT_INCLUDE_PATH} -I${CMAKE_CURRENT_BINARY_DIR}/include ${CMAKE_CXX_FLAGS}") +set(CONFIG_CFLAGS "${CONFIG_CFLAGS} -I\${BOUT_INCLUDE_PATH} -I${CMAKE_CURRENT_BINARY_DIR}/include ${CMAKE_CXX_FLAGS} -std=c++17") -target_compile_features(bout++ PUBLIC cxx_std_14) +target_compile_features(bout++ PUBLIC cxx_std_17) set_target_properties(bout++ PROPERTIES CXX_EXTENSIONS OFF) # Optional compiler features @@ -769,7 +774,7 @@ set(BOUT_HAS_PNETCDF OFF) # while for static builds we need the dependencies too if (BUILD_SHARED_LIBS) # Include rpath linker flag so user doesn't need to set LD_LIBRARY_PATH - set(CONFIG_LDFLAGS "${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}\$BOUT_LIB_PATH -L\$BOUT_LIB_PATH -lbout++ -lfmt") + set(CONFIG_LDFLAGS "${CMAKE_SHARED_LIBRARY_RUNTIME_CXX_FLAG}\$BOUT_LIB_PATH -L\$BOUT_LIB_PATH -lbout++ -lfmt ${CONFIG_LDFLAGS_SHARED}") else() set(CONFIG_LDFLAGS "${CONFIG_LDFLAGS}") endif() @@ -930,6 +935,7 @@ message(" SUNDIALS support : ${BOUT_HAS_SUNDIALS} HYPRE support : ${BOUT_HAS_HYPRE} NetCDF support : ${BOUT_HAS_NETCDF} + ADIOS2 support : ${BOUT_HAS_ADIOS2} FFTW support : ${BOUT_HAS_FFTW} LAPACK support : ${BOUT_HAS_LAPACK} OpenMP support : ${BOUT_USE_OPENMP} diff --git a/README.md b/README.md index 569f921c1d..5f774ad337 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,11 @@ For example, the following set of equations for magnetohydrodynamics (MHD): ![ddt_rho](http://latex.codecogs.com/png.latex?%5Cfrac%7B%5Cpartial%20%5Crho%7D%7B%5Cpartial%20t%7D%20%3D%20-%5Cmathbf%7Bv%7D%5Ccdot%5Cnabla%5Crho%20-%20%5Crho%5Cnabla%5Ccdot%5Cmathbf%7Bv%7D) + ![ddt_p](http://latex.codecogs.com/png.latex?%5Cfrac%7B%5Cpartial%20p%7D%7B%5Cpartial%20t%7D%20%3D%20-%5Cmathbf%7Bv%7D%5Ccdot%5Cnabla%20p%20-%20%5Cgamma%20p%5Cnabla%5Ccdot%5Cmathbf%7Bv%7D) + ![ddt_v](http://latex.codecogs.com/png.latex?%5Cfrac%7B%5Cpartial%20%5Cmathbf%7Bv%7D%7D%7B%5Cpartial%20t%7D%20%3D%20-%5Cmathbf%7Bv%7D%5Ccdot%5Cnabla%5Cmathbf%7Bv%7D%20+%20%5Cfrac%7B1%7D%7B%5Crho%7D%28-%5Cnabla%20p%20+%20%28%5Cnabla%5Ctimes%5Cmathbf%7BB%7D%29%5Ctimes%5Cmathbf%7BB%7D%29) + ![ddt_B](http://latex.codecogs.com/png.latex?%7B%7B%5Cfrac%7B%5Cpartial%20%5Cmathbf%7BB%7D%7D%7B%5Cpartial%20t%7D%7D%7D%20%3D%20%5Cnabla%5Ctimes%28%5Cmathbf%7Bv%7D%5Ctimes%5Cmathbf%7BB%7D%29) can be written simply as: @@ -43,7 +46,7 @@ The full code for this example can be found in the [orszag-tang example](examples/orszag-tang/mhd.cxx). Jointly developed by University of York (UK), LLNL, CCFE, DCU, DTU, -and other international partners. +and other international partners. See the Git logs for author details. Homepage found at [http://boutproject.github.io/](http://boutproject.github.io/) @@ -52,7 +55,6 @@ Homepage found at [http://boutproject.github.io/](http://boutproject.github.io/) * [Requirements](#requirements) * [Usage and installation](#usage-and-installation) * [Terms of use](#terms-of-use) -* [Overview of files](#overview-of-files) * [Contributing](#contributing) * [License](#license) @@ -60,24 +62,23 @@ Homepage found at [http://boutproject.github.io/](http://boutproject.github.io/) BOUT++ needs the following: -* A C++14 compiler +* A C++17 compiler * MPI * NetCDF BOUT++ has the following optional dependencies: -* FFTW3 (strongly recommended!) -* OpenMP -* PETSc -* SLEPc -* ARKODE -* IDA -* CVODE +* [FFTW3](https://www.fftw.org/) (strongly recommended!) +* [SUNDIALS](https://computing.llnl.gov/projects/sundials): CVODE, IDA, ARKODE +* [PETSc](https://petsc.org) +* [ADIOS2](https://adios2.readthedocs.io/) +* [SLEPc](https://slepc.upv.es/) * LAPACK +* OpenMP * Score-p (for performance diagnostics) ## Usage and installation -Please see the [users manual](http://bout-dev.readthedocs.io) +Please see the [users manual](http://bout-dev.readthedocs.io). ## Terms of use @@ -105,58 +106,14 @@ You can convert the CITATION.cff file into a Bibtex file as follows: pip3 install --user cffconvert cffconvert -if CITATION.cff -f bibtex -of CITATION.bib -## Overview of files - -This directory contains - -* **bin** Files for setting the BOUT++ configuration -* **examples** Example models and test codes -* **externalpackages** External packages needed for installing BOUT++ -* **include** Header files used in BOUT++ -* **manual** Manuals and documentation (also [doxygen](http://www.stack.nl/~dimitri/doxygen/) documentation) -* **src** The main code directory -* **CITATION** Contains the paper citation for BOUT++ -* **LICENSE** LGPL license -* **LICENSE.GPL** GPL license -* **tools** Tools for helping with analysis, mesh generation, and data managment - - * **archiving** Routines for managing input/output files e.g. compressing data, converting formats, and managing runs - * **cyl_and_helimak_grids** IDL codes for generating cylindrical and helimak grids - * **eigensolver** Matlab routines for solving eigenmodes - * **idllib** Analysis codes in IDL. Add this to your IDL_PATH environment variable - * **line_tracing** IDL routines for line tracing of field lines - * **line_tracing_v2** Newer version of the IDL routines for line tracing of field lines - * **mathematicalib** Library for post processing using Mathematica - * **matlablib** Library for post processing using MATLAB - * **numlib** Numerical IDL routines - * **octave** Routines for post processing using octave - * **plasmalib** IDL routines for calculation of plasma parameters - * **pdb2idl** Library to read Portable Data Binary (PDB) files into IDL - * **pylib** Analysis codes in Python - - * **boutdata** Routines to simplify accessing BOUT++ output - * **boututils** Some useful routines for accessing and plotting data - * **post_bout** Routines for post processing in BOUT++ - - * **slab** IDL routine for grid generation of a slab - * **tokamak_grids** Code to generate input grids for tokamak equilibria - - * **gridgen** Grid generator in IDL. Hypnotoad GUI for converting G-EQDSK files into a flux-aligned orthogonal grid. - * **elite** Convert ELITE .eqin files into an intermediate binary file - * **gato** Convert DSKGATO files into intermediate binary format - * **all** Convert the intermediate binary file into BOUT++ input grid - * **coils** Routines for calculating the field due to external RMP coils and adding to existing equilibria - * **cyclone** Generate cyclone test cases (concentric circle "equilibrium" for local flux-surface calculations) - * **py_gridgen** Translation" into python of the corresponding IDL routines in the folder gridgen - * **shifted_circle** Produce shifted cirle equilibria input grids ## Contributing -See [CONTRIBUTING.md](CONTRIBUTING.md). +See [CONTRIBUTING.md](CONTRIBUTING.md) and the [manual page](https://bout-dev.readthedocs.io/en/stable/developer_docs/contributing.html) ## License -Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu +Copyright 2010-2024 BOUT++ contributors BOUT++ is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by @@ -171,15 +128,7 @@ GNU Lesser General Public License for more details. A copy of the LGPL license is in [LICENSE](LICENSE). Since this is based on (and refers to) the GPL, this is included in [LICENSE.GPL](LICENSE.GPL). -Some of the autoconf macros under [m4](m4) are licensed under -GPLv3. These are not necessary to either build or run BOUT++, but are -used in the creation of [configure](configure) from -[configure.ac](configure.ac), and are provided as a courtesy to -developers. You are free to substitute them with other autoconf macros -that provide equivalent functionality. - BOUT++ links by default with some GPL licensed libraries. Thus if you compile BOUT++ with any of them, BOUT++ will automatically be licensed as GPL. Thus if you want to use BOUT++ with GPL non-compatible code, make sure to compile without GPLed code. - diff --git a/autoconf_build_defines.hxx.in b/autoconf_build_defines.hxx.in deleted file mode 100644 index a1f23082a1..0000000000 --- a/autoconf_build_defines.hxx.in +++ /dev/null @@ -1,102 +0,0 @@ -/* autoconf_build_defines.hxx.in. Generated from configure.ac by autoheader. */ - -/* Runtime error checking level */ -#undef BOUT_CHECK_LEVEL - -/* ARKODE support */ -#undef BOUT_HAS_ARKODE - -/* Caliper support */ -#undef BOUT_HAS_CALIPER - -/* CVODE support */ -#undef BOUT_HAS_CVODE - -/* FFTW support */ -#undef BOUT_HAS_FFTW - -/* NLS support */ -#undef BOUT_HAS_GETTEXT - -/* Hypre support */ -#undef BOUT_HAS_HYPRE - -/* IDA support */ -#undef BOUT_HAS_IDA - -/* LAPACK support */ -#undef BOUT_HAS_LAPACK - -/* NETCDF support */ -#undef BOUT_HAS_LEGACY_NETCDF - -/* NETCDF support */ -#undef BOUT_HAS_NETCDF - -/* PETSc support */ -#undef BOUT_HAS_PETSC - -/* PNETCDF support */ -#undef BOUT_HAS_PNETCDF - -/* Compiler PRETTYFUNCTION support */ -#undef BOUT_HAS_PRETTY_FUNCTION - -/* PVODE support */ -#undef BOUT_HAS_PVODE - -/* RAJA support */ -#undef BOUT_HAS_RAJA - -/* Score-P support */ -#undef BOUT_HAS_SCOREP - -/* SLEPc support */ -#undef BOUT_HAS_SLEPC - -/* SUNDIALS support */ -#undef BOUT_HAS_SUNDIALS - -/* Umpire support */ -#undef BOUT_HAS_UMPIRE - -/* Use libuuid for UUID generation */ -#undef BOUT_HAS_UUID_SYSTEM_GENERATOR - -/* Type of the metric fields */ -#undef BOUT_METRIC_TYPE - -/* OpenMP schedule */ -#undef BOUT_OPENMP_SCHEDULE - -/* Enable backtrace in exceptions */ -#undef BOUT_USE_BACKTRACE - -/* Enable color logs option */ -#undef BOUT_USE_COLOR - -/* Enable CUDA */ -#undef BOUT_HAS_CUDA - -/* Is the metric field 3D */ -#undef BOUT_USE_METRIC_3D - -/* Enable MsgStack for traces */ -#undef BOUT_USE_MSGSTACK - -/* Enable OpenMP */ -#undef BOUT_USE_OPENMP - -/* Enabled extra debug output */ -#undef BOUT_USE_OUTPUT_DEBUG - -/* Enable floating point exceptions */ -#undef BOUT_USE_SIGFPE - -/* Enable signal handlers */ -#undef BOUT_USE_SIGNAL - -/* Enable field name tracking */ -#undef BOUT_USE_TRACK - -// NOTE TO DEVELOPERS: PLEASE KEEP THIS LINE AND DELETE AUTOGENERATED CONTENT BELOW! diff --git a/bin/bout-build-deps.sh b/bin/bout-build-deps.sh index 19e3b2a0d3..d96d500dc9 100755 --- a/bin/bout-build-deps.sh +++ b/bin/bout-build-deps.sh @@ -98,7 +98,7 @@ netcdf() { nccxx() { cd $BUILD - wget -c ftp://ftp.unidata.ucar.edu/pub/netcdf/netcdf-cxx4-$NCCXXVER.tar.gz || : + wget -c https://downloads.unidata.ucar.edu/netcdf-cxx/$NCCXXVER/netcdf-cxx4-$NCCXXVER.tar.gz || : tar -xf netcdf-cxx4-$NCCXXVER.tar.gz cd netcdf-cxx4-$NCCXXVER CPPFLAGS="-I$PREFIX/include" LDFLAGS="-L$PREFIX/lib/" ./configure --prefix=$PREFIX $NCCXXFLAGS @@ -286,17 +286,17 @@ set -x ## Setup folders and links setup ## Build and install hdf5 -hdf5 +test $NO_HDF5 || hdf5 ## Build and install netcdf -netcdf +test $NO_NETCDF || netcdf ## Build and install C++ interface for netcdf -nccxx +test $NO_NCXX || nccxx ## Build and install FFTW -fftw +test $NO_FFTW || fftw ## Build and install Sundials -sundials +test $NO_SUNDIALS || sundials ## Build and install PETSc -petsc +test $NO_PETSC || petsc ## Download BOUT++ submodules submod # Install python packages diff --git a/bin/bout-config.in b/bin/bout-config.in index 697d3ddc71..b5a62a42eb 100755 --- a/bin/bout-config.in +++ b/bin/bout-config.in @@ -29,6 +29,7 @@ idlpath="@IDLCONFIGPATH@" pythonpath="@PYTHONCONFIGPATH@" has_netcdf="@BOUT_HAS_NETCDF@" +has_adios2="@BOUT_HAS_ADIOS2@" has_legacy_netcdf="@BOUT_HAS_LEGACY_NETCDF@" has_pnetcdf="@BOUT_HAS_PNETCDF@" has_pvode="@BOUT_HAS_PVODE@" @@ -70,17 +71,18 @@ Available values for OPTION include: --idl IDL path --python Python path - --has-netcdf NetCDF file support + --has-netcdf NetCDF file support + --has-adios2 ADIOS2 file support --has-legacy-netcdf Legacy NetCDF file support - --has-pnetcdf Parallel NetCDF file support - --has-pvode PVODE solver support - --has-cvode SUNDIALS CVODE solver support - --has-ida SUNDIALS IDA solver support - --has-lapack LAPACK support - --has-petsc PETSc support - --has-hypre Hypre support - --has-slepc SLEPc support - --has-nls Natural Language Support + --has-pnetcdf Parallel NetCDF file support + --has-pvode PVODE solver support + --has-cvode SUNDIALS CVODE solver support + --has-ida SUNDIALS IDA solver support + --has-lapack LAPACK support + --has-petsc PETSc support + --has-hypre Hypre support + --has-slepc SLEPc support + --has-nls Natural Language Support --petsc-has-sundials @@ -109,6 +111,7 @@ all() echo " --python -> $pythonpath" echo echo " --has-netcdf -> $has_netcdf" + echo " --has-adios -> $has_adios" echo " --has-legacy-netcdf -> $has_legacy_netcdf" echo " --has-pnetcdf -> $has_pnetcdf" echo " --has-pvode -> $has_pvode" @@ -120,6 +123,7 @@ all() echo " --has-slepc -> $has_slepc" echo " --has-arkode -> $has_arkode" echo " --has-nls -> $has_nls" + echo " --has-openmp -> $has_openmp" echo echo " --petsc-has-sundials -> $petsc_has_sundials" echo @@ -197,6 +201,10 @@ while test $# -gt 0; do echo $has_netcdf ;; + --has-adios) + echo $has_adios + ;; + --has-legacy-netcdf) echo $has_legacy_netcdf ;; diff --git a/bout++Config.cmake.in b/bout++Config.cmake.in index e33e950e6f..5af0dc43ea 100644 --- a/bout++Config.cmake.in +++ b/bout++Config.cmake.in @@ -15,6 +15,7 @@ set(BOUT_USE_METRIC_3D @BOUT_USE_METRIC_3D@) set(BOUT_HAS_PVODE @BOUT_HAS_PVODE@) set(BOUT_HAS_NETCDF @BOUT_HAS_NETCDF@) +set(BOUT_HAS_ADIOS2 @BOUT_HAS_ADIOS2@) set(BOUT_HAS_FFTW @BOUT_HAS_FFTW@) set(BOUT_HAS_LAPACK @BOUT_HAS_LAPACK@) set(BOUT_HAS_PETSC @BOUT_HAS_PETSC@) diff --git a/cmake/FindCython.cmake b/cmake/FindCython.cmake index 76f43480d9..3b98cde89e 100644 --- a/cmake/FindCython.cmake +++ b/cmake/FindCython.cmake @@ -10,7 +10,7 @@ # CYTHON_FOUND - true if Cython was found # CYTHON_VERSION - Cython version -execute_process(COMMAND ${Python_EXECUTABLE} -c "import cython ; print(cython.__version__)" +execute_process(COMMAND ${Python3_EXECUTABLE} -c "import cython ; print(cython.__version__)" RESULT_VARIABLE _cython_runs OUTPUT_VARIABLE CYTHON_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE diff --git a/cmake/FindNumpy.cmake b/cmake/FindNumpy.cmake index 201bc19221..b6de6e3e35 100644 --- a/cmake/FindNumpy.cmake +++ b/cmake/FindNumpy.cmake @@ -12,32 +12,32 @@ # Numpy_INCLUDE_DIR -find_package(Python 3.6 COMPONENTS Interpreter Development) +find_package(Python3 3.6 COMPONENTS Interpreter Development) -if (NOT Python_FOUND) +if (NOT Python3_FOUND) message(STATUS "Could not find numpy as python was not found. Maybe the developement package is missing?") - set(Numpy_FOUND ${Python_FOUND}) + set(Numpy_FOUND ${Python3_FOUND}) return() endif() if (NOT Numpy_FOUND) - execute_process(COMMAND ${Python_EXECUTABLE} -c "import numpy ; print(numpy.__version__)" + execute_process(COMMAND ${Python3_EXECUTABLE} -c "import numpy ; print(numpy.__version__)" OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE Numpy_VERSION ) - execute_process(COMMAND ${Python_EXECUTABLE} -c "import numpy ; print(numpy.get_include())" + execute_process(COMMAND ${Python3_EXECUTABLE} -c "import numpy ; print(numpy.get_include())" OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE _numpy_include_dirs ) endif() if (Numpy_DEBUG) - message(STATUS "Looking for numpy headers in: ${_numpy_include_dirs} ${PYTHON_INCLUDE_DIR}") + message(STATUS "Looking for numpy headers in: ${_numpy_include_dirs} ${Python3_INCLUDE_DIRS}") endif() find_path(Numpy_INCLUDE_DIR numpy/arrayobject.h - PATHS "${_numpy_include_dirs}" "${PYTHON_INCLUDE_DIR}" + PATHS "${_numpy_include_dirs}" "${Python3_INCLUDE_DIRS}" PATH_SUFFIXES numpy/core/include ) diff --git a/cmake/FindPackageMultipass.cmake b/cmake/FindPackageMultipass.cmake index 2452096b56..99bbace448 100644 --- a/cmake/FindPackageMultipass.cmake +++ b/cmake/FindPackageMultipass.cmake @@ -108,7 +108,7 @@ macro (MULTIPASS_C_SOURCE_RUNS includes libraries source runs) endmacro (MULTIPASS_C_SOURCE_RUNS) macro (MULTIPASS_SOURCE_COMPILES includes libraries source runs language) - include (Check${language}SourceRuns) + include (Check${language}SourceCompiles) # This is a ridiculous hack. CHECK_${language}_SOURCE_* thinks that if the # *name* of the return variable doesn't change, then the test does # not need to be re-run. We keep an internal count which we diff --git a/cmake/FindSUNDIALS.cmake b/cmake/FindSUNDIALS.cmake index 1ecb5db429..15b266d06a 100644 --- a/cmake/FindSUNDIALS.cmake +++ b/cmake/FindSUNDIALS.cmake @@ -104,16 +104,8 @@ endforeach() if (SUNDIALS_INCLUDE_DIR) file(READ "${SUNDIALS_INCLUDE_DIR}/sundials_config.h" SUNDIALS_CONFIG_FILE) - string(FIND "${SUNDIALS_CONFIG_FILE}" "SUNDIALS_PACKAGE_VERSION" index) - if("${index}" LESS 0) - # Version >3 - set(SUNDIALS_VERSION_REGEX_PATTERN - ".*#define SUNDIALS_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*") - else() - # Version <3 - set(SUNDIALS_VERSION_REGEX_PATTERN - ".*#define SUNDIALS_PACKAGE_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*") - endif() + set(SUNDIALS_VERSION_REGEX_PATTERN + ".*#define SUNDIALS_VERSION \"([0-9]+)\\.([0-9]+)\\.([0-9]+)\".*") string(REGEX MATCH ${SUNDIALS_VERSION_REGEX_PATTERN} _ "${SUNDIALS_CONFIG_FILE}") set(SUNDIALS_VERSION_MAJOR ${CMAKE_MATCH_1} CACHE STRING "") set(SUNDIALS_VERSION_MINOR ${CMAKE_MATCH_2} CACHE STRING "") diff --git a/cmake/SetupBOUTThirdParty.cmake b/cmake/SetupBOUTThirdParty.cmake index 78dfc6b56e..9c49fe6fdc 100644 --- a/cmake/SetupBOUTThirdParty.cmake +++ b/cmake/SetupBOUTThirdParty.cmake @@ -8,6 +8,9 @@ endif () # determined in SetupCompilers.cmake if (BOUT_USE_OPENMP) target_link_libraries(bout++ PUBLIC OpenMP::OpenMP_CXX) + set(CONFIG_LDFLAGS "${CONFIG_LDFLAGS} -fopenmp") + set(CONFIG_LDFLAGS_SHARED "${CONFIG_LDFLAGS_SHARED} -fopenmp") + set(CONFIG_CFLAGS "${CONFIG_CFLAGS} -fopenmp") endif() # determined in SetupCompilers.cmake @@ -19,9 +22,10 @@ if (BOUT_HAS_CUDA) set(BOUT_SOURCES_CXX ${BOUT_SOURCES}) list(FILTER BOUT_SOURCES_CXX INCLUDE REGEX ".*\.cxx") - set_source_files_properties(${BOUT_SOURCES_CXX} PROPERTIES LANGUAGE CUDA ) + # NOTE: CUDA inherits the CXX standard setting from the top-level + # compile features, set for the bout++ target. + set_source_files_properties(${BOUT_SOURCES_CXX} PROPERTIES LANGUAGE CUDA) find_package(CUDAToolkit) - set_target_properties(bout++ PROPERTIES CUDA_STANDARD 14) set_target_properties(bout++ PROPERTIES CUDA_SEPARABLE_COMPILATION ON) set_target_properties(bout++ PROPERTIES POSITION_INDEPENDENT_CODE ON) set_target_properties(bout++ PROPERTIES LINKER_LANGUAGE CUDA) @@ -156,6 +160,7 @@ option(BOUT_USE_NETCDF "Enable support for NetCDF output" ON) option(BOUT_DOWNLOAD_NETCDF_CXX4 "Download and build netCDF-cxx4" OFF) if (BOUT_USE_NETCDF) if (BOUT_DOWNLOAD_NETCDF_CXX4) + message(STATUS "Downloading and configuring NetCDF-cxx4") include(FetchContent) FetchContent_Declare( netcdf-cxx4 @@ -185,6 +190,44 @@ endif() message(STATUS "NetCDF support: ${BOUT_USE_NETCDF}") set(BOUT_HAS_NETCDF ${BOUT_USE_NETCDF}) +option(BOUT_USE_ADIOS2 "Enable support for ADIOS output" ON) +option(BOUT_DOWNLOAD_ADIOS2 "Download and build ADIOS2" OFF) +if (BOUT_USE_ADIOS2) + if (BOUT_DOWNLOAD_ADIOS2) + message(STATUS "Downloading and configuring ADIOS2") + include(FetchContent) + FetchContent_Declare( + adios2 + GIT_REPOSITORY https://github.com/ornladios/ADIOS2.git + GIT_TAG origin/master + GIT_SHALLOW 1 + ) + set(ADIOS2_USE_MPI ON CACHE BOOL "" FORCE) + set(ADIOS2_USE_Fortran OFF CACHE BOOL "" FORCE) + set(ADIOS2_USE_Python OFF CACHE BOOL "" FORCE) + set(ADIOS2_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) + # Disable testing, or ADIOS will try to find or install GTEST + set(BUILD_TESTING OFF CACHE BOOL "" FORCE) + # Note: SST requires but doesn't check at configure time + set(ADIOS2_USE_SST OFF CACHE BOOL "" FORCE) + FetchContent_MakeAvailable(adios2) + target_link_libraries(bout++ PUBLIC adios2::cxx11_mpi) + message(STATUS "ADIOS2 done configuring") + else() + find_package(ADIOS2) + if (ADIOS2_FOUND) + ENABLE_LANGUAGE(C) + find_package(MPI REQUIRED COMPONENTS C) + target_link_libraries(bout++ PUBLIC adios2::cxx11_mpi MPI::MPI_C) + else() + set(BOUT_USE_ADIOS2 OFF) + endif() + endif() +endif() +message(STATUS "ADIOS2 support: ${BOUT_USE_ADIOS2}") +set(BOUT_HAS_ADIOS2 ${BOUT_USE_ADIOS2}) + + option(BOUT_USE_FFTW "Enable support for FFTW" ON) if (BOUT_USE_FFTW) find_package(FFTW REQUIRED) @@ -238,19 +281,27 @@ if (BOUT_USE_SUNDIALS) include(FetchContent) FetchContent_Declare( sundials - GIT_REPOSITORY https://github.com/ZedThree/sundials - GIT_TAG cmake-export-fixes + GIT_REPOSITORY https://github.com/LLNL/sundials + GIT_TAG v7.0.0 ) # Note: These are settings for building SUNDIALS set(EXAMPLES_ENABLE_C OFF CACHE BOOL "" FORCE) set(EXAMPLES_INSTALL OFF CACHE BOOL "" FORCE) set(ENABLE_MPI ${BOUT_USE_MPI} CACHE BOOL "" FORCE) set(ENABLE_OPENMP OFF CACHE BOOL "" FORCE) - set(BUILD_STATIC_LIBS OFF CACHE BOOL "" FORCE) + if (BUILD_SHARED_LIBS) + set(BUILD_STATIC_LIBS OFF CACHE BOOL "" FORCE) + else() + set(BUILD_STATIC_LIBS ON CACHE BOOL "" FORCE) + endif() FetchContent_MakeAvailable(sundials) message(STATUS "SUNDIALS done configuring") else() + enable_language(C) find_package(SUNDIALS REQUIRED) + if (SUNDIALS_VERSION VERSION_LESS 4.0.0) + message(FATAL_ERROR "SUNDIALS_VERSION 4.0.0 or newer is required. Found version ${SUNDIALS_VERSION}.") + endif() endif() target_link_libraries(bout++ PUBLIC SUNDIALS::nvecparallel) target_link_libraries(bout++ PUBLIC SUNDIALS::cvode) diff --git a/cmake_build_defines.hxx.in b/cmake_build_defines.hxx.in index a637dbc46a..4d63a01b7d 100644 --- a/cmake_build_defines.hxx.in +++ b/cmake_build_defines.hxx.in @@ -13,6 +13,7 @@ #cmakedefine01 BOUT_HAS_IDA #cmakedefine01 BOUT_HAS_LAPACK #cmakedefine01 BOUT_HAS_NETCDF +#cmakedefine01 BOUT_HAS_ADIOS2 #cmakedefine01 BOUT_HAS_PETSC #cmakedefine01 BOUT_HAS_PRETTY_FUNCTION #cmakedefine01 BOUT_HAS_PVODE diff --git a/configure b/configure deleted file mode 100755 index 359fd6d7a9..0000000000 --- a/configure +++ /dev/null @@ -1,17273 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for BOUT++ 5.1.0. -# -# Report bugs to . -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org and bd512@york.ac.uk -$0: about your system, including any error possibly output -$0: before this message. Then install a modern shell, or -$0: manually run the script under such a shell if you do -$0: have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='BOUT++' -PACKAGE_TARNAME='bout--' -PACKAGE_VERSION='5.1.0' -PACKAGE_STRING='BOUT++ 5.1.0' -PACKAGE_BUGREPORT='bd512@york.ac.uk' -PACKAGE_URL='' - -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -gt_needs= -ac_subst_vars='SLEPC_ARCH -SLEPC_DIR -SLEPC_MAKE_INCLUDE -PETSC_ARCH -PETSC_DIR -PETSC_MAKE_INCLUDE -PETSC_HAS_SUNDIALS -BOUT_METRIC_TYPE -BOUT_USE_MSGSTACK -BOUT_USE_TRACK -BOUT_USE_SIGNAL -BOUT_USE_SIGFPE -BOUT_USE_OPENMP -BOUT_USE_OUTPUT_DEBUG -BOUT_USE_COLOR -BOUT_USE_BACKTRACE -BOUT_HAS_UUID_SYSTEM_GENERATOR -BOUT_HAS_SUNDIALS -BOUT_HAS_SLEPC -BOUT_HAS_SCOREP -BOUT_HAS_PVODE -BOUT_HAS_PRETTY_FUNCTION -BOUT_HAS_PNETCDF -BOUT_HAS_HYPRE -BOUT_HAS_PETSC -BOUT_HAS_LEGACY_NETCDF -BOUT_HAS_NETCDF -BOUT_HAS_LAPACK -BOUT_HAS_IDA -BOUT_HAS_GETTEXT -BOUT_HAS_FFTW -BOUT_HAS_CVODE -BOUT_HAS_ARKODE -BOUT_OPENMP_SCHEDULE -BOUT_CHECK_LEVEL -BOUT_REVISION -BOUT_VERSION_TAG -BOUT_VERSION_PATCH -BOUT_VERSION_MINOR -BOUT_VERSION_MAJOR -BOUT_VERSION -SHARED_EXTRA -STATIC_EXTRA -LIB_TO_BUILD -PYTHONCONFIGPATH -IDLCONFIGPATH -PREFIX -OWN_MPARK -MPARK_INCLUDE -MPARK_VARIANT_INCLUDE_PATH -FMT_INCLUDE_PATH -BOUT_INCLUDE_PATH -BOUT_LIB_PATH -CONFIG_LDFLAGS -CONFIG_CFLAGS -BOUT_HAS_CALIPER -BOUT_HAS_UMPIRE -BOUT_HAS_RAJA -BOUT_HAS_CUDA -LTLIBOBJS -POSUB -LTLIBINTL -LIBINTL -INTLLIBS -LTLIBICONV -LIBICONV -INTL_MACOSX_LIBS -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -ac_ct_CC -CFLAGS -CC -XGETTEXT_EXTRA_OPTIONS -MSGMERGE -XGETTEXT_015 -XGETTEXT -GMSGFMT_015 -MSGFMT_015 -GMSGFMT -MSGFMT -GETTEXT_MACRO_VERSION -USE_NLS -SCOREPPATH -sundials_config -PETSC_LIBS -PETSC_CFLAGS -PKG_CONFIG_LIBDIR -PKG_CONFIG_PATH -PKG_CONFIG -NCMPIDUMP_PATH -NCCONF -fftw_path -works -COVERAGE_FLAGS -CODE_COVERAGE_RULES -CODE_COVERAGE_LDFLAGS -CODE_COVERAGE_LIBS -CODE_COVERAGE_CXXFLAGS -CODE_COVERAGE_CFLAGS -CODE_COVERAGE_CPPFLAGS -GENHTML -LCOV -GCOV -CODE_COVERAGE_ENABLED -CODE_COVERAGE_ENABLED_FALSE -CODE_COVERAGE_ENABLED_TRUE -SED -OPENMP_CXXFLAGS -LIBOBJS -EGREP -GREP -CXXCPP -HAVE_CXX14 -ARFLAGS -RANLIB -MAKE -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -SET_MAKE -LN_S -OBJEXT -EXEEXT -ac_ct_CXX -CPPFLAGS -CXX -ac_ct_MPICXX -MPICXX -PRECON_SOURCE -MKDIR_P -LDFLAGS -CXXFLAGS -EXTRA_LIBS -EXTRA_INCS -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -with_netcdf -with_pnetcdf -with_ida -with_cvode -with_sundials -with_fftw -with_lapack -with_petsc -with_slepc -with_pvode -with_arkode -with_scorep -with_hypre -with_system_mpark -with_system_uuid -enable_warnings -enable_checks -enable_msgstack -enable_signal -enable_color -enable_track -enable_debug -enable_output_debug -enable_optimize -enable_sigfpe -enable_backtrace -enable_shared -enable_static -enable_openmp -with_openmp_schedule -enable_pvode_openmp -enable_metric_3d -with_gcov -enable_code_coverage -enable_nls -with_gnu_ld -enable_rpath -with_libiconv_prefix -with_libintl_prefix -' - ac_precious_vars='build_alias -host_alias -target_alias -EXTRA_INCS -EXTRA_LIBS -CXXFLAGS -LDFLAGS -LIBS -MPICXX -CXX -CPPFLAGS -CCC -CXXCPP -PKG_CONFIG -PKG_CONFIG_PATH -PKG_CONFIG_LIBDIR -PETSC_CFLAGS -PETSC_LIBS -CC -CFLAGS' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures BOUT++ 5.1.0 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/bout--] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of BOUT++ 5.1.0:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --disable-warnings Disable compiler warnings - --enable-checks=no/1/2/3 - Set run-time checking level - --enable-msgstack=no/yes - Enable MstStack for backtrace. Default based on - check level. - --disable-signal Disable SEGFAULT handling - --disable-color Disable -c option to color output - --enable-track Enable variable tracking - --enable-debug Enable all debugging flags - --enable-output-debug Enable some extra debugging output - --enable-optimize=no/1/2/3/4 - Enable optimization - --enable-sigfpe Enable FloatingPointExceptions - --disable-backtrace Disable function backtrace - --enable-shared Enable building bout++ into an shared object - --enable-static Enable building bout++ into an static library - --enable-openmp Enable building with OpenMP support - --enable-pvode-openmp Enable building PVODE with OpenMP support - --enable-metric-3d Use Field3D to store coordinates metric data - --disable-openmp do not use OpenMP - --enable-code-coverage Whether to enable code coverage support - --disable-nls do not use Native Language Support - --disable-rpath do not hardcode runtime library paths - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-netcdf Enable support for netCDF files - --with-pnetcdf Set path to Parallel NetCDF library - --with-ida=/path/to/ida Use the SUNDIALS IDA solver - --with-cvode Use the SUNDIALS CVODE solver - --with-sundials Use CVODE and IDA - --with-fftw Set directory of FFTW3 library - --with-lapack Use the LAPACK library - --with-petsc Enable PETSc interface - --with-slepc Enable SLEPc interface - --with-pvode Build and enable PVODE 98 (DEFAULT) - --with-arkode Use the SUNDIALS ARKODE solver - --with-scorep Enable support for scorep based instrumentation - --with-hypre Enable support for HYPRE - --with-system-mpark Use mpark.variant already installed rather then the - bundled one - --with-system-uuid Use libuuid to generate UUIDs - --with-openmp-schedule=static/dynamic/guided/auto - Set OpenMP schedule (default: static) - --with-gcov=GCOV use given GCOV for coverage (GCOV=gcov). - --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-libiconv-prefix[=DIR] search for libiconv in DIR/include and DIR/lib - --without-libiconv-prefix don't search for libiconv in includedir and libdir - --with-libintl-prefix[=DIR] search for libintl in DIR/include and DIR/lib - --without-libintl-prefix don't search for libintl in includedir and libdir - -Some influential environment variables: - EXTRA_INCS Extra compile flags - EXTRA_LIBS Extra linking flags - CXXFLAGS Extra compile flags - LDFLAGS Extra linking flags - LIBS Extra linking libraries - MPICXX MPI C++ compiler command - CXX C++ compiler command - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CXXCPP C++ preprocessor - PKG_CONFIG path to pkg-config utility - PKG_CONFIG_PATH - directories to add to pkg-config's search path - PKG_CONFIG_LIBDIR - path overriding pkg-config's built-in search path - PETSC_CFLAGS - C compiler flags for PETSC, overriding pkg-config - PETSC_LIBS linker flags for PETSC, overriding pkg-config - CC C compiler command - CFLAGS C compiler flags - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to . -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -BOUT++ configure 5.1.0 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_cxx_try_compile LINENO -# ---------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_compile - -# ac_fn_cxx_try_link LINENO -# ------------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_link - -# ac_fn_cxx_try_cpp LINENO -# ------------------------ -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_cxx_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_cpp - -# ac_fn_cxx_try_run LINENO -# ------------------------ -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_cxx_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_cxx_try_run - -# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES -# --------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_cxx_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## ------------------------------- ## -## Report this to bd512@york.ac.uk ## -## ------------------------------- ##" - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_cxx_check_header_mongrel - -# ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES -# --------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_cxx_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_cxx_check_header_compile - -# ac_fn_cxx_check_func LINENO FUNC VAR -# ------------------------------------ -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_cxx_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_cxx_check_func - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by BOUT++ $as_me 5.1.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -gt_needs="$gt_needs " -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -ac_aux_dir= -for ac_dir in build-aux "$srcdir"/build-aux; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ./configure is deprecated and will be removed in a future version, please use CMake instead" >&5 -$as_echo "$as_me: WARNING: ./configure is deprecated and will be removed in a future version, please use CMake instead" >&2;} - - -# Check whether --with-netcdf was given. -if test "${with_netcdf+set}" = set; then : - withval=$with_netcdf; -fi - - -# Check whether --with-pnetcdf was given. -if test "${with_pnetcdf+set}" = set; then : - withval=$with_pnetcdf; -fi - - -# Check whether --with-ida was given. -if test "${with_ida+set}" = set; then : - withval=$with_ida; -fi - - -# Check whether --with-cvode was given. -if test "${with_cvode+set}" = set; then : - withval=$with_cvode; -fi - - -# Check whether --with-sundials was given. -if test "${with_sundials+set}" = set; then : - withval=$with_sundials; -fi - - -# Check whether --with-fftw was given. -if test "${with_fftw+set}" = set; then : - withval=$with_fftw; -fi - - -# Check whether --with-lapack was given. -if test "${with_lapack+set}" = set; then : - withval=$with_lapack; -else - with_lapack=guess -fi - - -# Check whether --with-petsc was given. -if test "${with_petsc+set}" = set; then : - withval=$with_petsc; -else - with_petsc=no -fi - - -# Check whether --with-slepc was given. -if test "${with_slepc+set}" = set; then : - withval=$with_slepc; -else - with_slepc=no -fi - - -# Check whether --with-pvode was given. -if test "${with_pvode+set}" = set; then : - withval=$with_pvode; -fi - - -# Check whether --with-arkode was given. -if test "${with_arkode+set}" = set; then : - withval=$with_arkode; -fi - - -# Check whether --with-scorep was given. -if test "${with_scorep+set}" = set; then : - withval=$with_scorep; -else - with_scorep=no -fi - - -# Check whether --with-hypre was given. -if test "${with_hypre+set}" = set; then : - withval=$with_hypre; -else - with_hypre=no -fi - - - -# Check whether --with-system_mpark was given. -if test "${with_system_mpark+set}" = set; then : - withval=$with_system_mpark; -else - with_system_mpark=auto -fi - - -# Check whether --with-system_uuid was given. -if test "${with_system_uuid+set}" = set; then : - withval=$with_system_uuid; -else - with_system_uuid=auto -fi - - -# Check whether --enable-warnings was given. -if test "${enable_warnings+set}" = set; then : - enableval=$enable_warnings; -fi - -# Check whether --enable-checks was given. -if test "${enable_checks+set}" = set; then : - enableval=$enable_checks; -else - enable_checks=default -fi - -# Check whether --enable-msgstack was given. -if test "${enable_msgstack+set}" = set; then : - enableval=$enable_msgstack; -else - enable_msgstack=maybe -fi - -# Check whether --enable-signal was given. -if test "${enable_signal+set}" = set; then : - enableval=$enable_signal; -fi - -# Check whether --enable-color was given. -if test "${enable_color+set}" = set; then : - enableval=$enable_color; -fi - -# Check whether --enable-track was given. -if test "${enable_track+set}" = set; then : - enableval=$enable_track; -fi - -# Check whether --enable-debug was given. -if test "${enable_debug+set}" = set; then : - enableval=$enable_debug; -fi - -# Check whether --enable-output_debug was given. -if test "${enable_output_debug+set}" = set; then : - enableval=$enable_output_debug; -fi - -# Check whether --enable-optimize was given. -if test "${enable_optimize+set}" = set; then : - enableval=$enable_optimize; -fi - -# Check whether --enable-sigfpe was given. -if test "${enable_sigfpe+set}" = set; then : - enableval=$enable_sigfpe; -fi - -# Check whether --enable-backtrace was given. -if test "${enable_backtrace+set}" = set; then : - enableval=$enable_backtrace; -else - enable_backtrace=maybe -fi - -# Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : - enableval=$enable_shared; -else - enable_shared=no -fi - -# Check whether --enable-static was given. -if test "${enable_static+set}" = set; then : - enableval=$enable_static; -else - enable_static=auto -fi - -# Check whether --enable-openmp was given. -if test "${enable_openmp+set}" = set; then : - enableval=$enable_openmp; -else - enable_openmp=no -fi - - -# Check whether --with-openmp_schedule was given. -if test "${with_openmp_schedule+set}" = set; then : - withval=$with_openmp_schedule; -else - with_openmp_schedule=static -fi - -# Check whether --enable-pvode_openmp was given. -if test "${enable_pvode_openmp+set}" = set; then : - enableval=$enable_pvode_openmp; -else - enable_pvode_openmp=no -fi - -# Check whether --enable-metric_3d was given. -if test "${enable_metric_3d+set}" = set; then : - enableval=$enable_metric_3d; -else - enable_metric_3d=no -fi - - - - - -file_formats="" # Record which file formats are being supported - -# Delete the build log from last time -rm -f config-build.log - -# only keep BOUT related undefs -if ! grep -q 'NOTE TO DEVEL' autoconf_build_defines.hxx.in ; then - grep 'undef BOUT' -B 4 -A 1 autoconf_build_defines.hxx.in > autoconf_build_defines.hxx.in.tmp - echo '// NOTE TO DEVELOPERS: PLEASE KEEP THIS LINE AND DELETE AUTOGENERATED CONTENT BELOW!' >> autoconf_build_defines.hxx.in.tmp - mv autoconf_build_defines.hxx.in.tmp autoconf_build_defines.hxx.in -fi - - - - - -LIBS="$LIBS $LDLIBS" - - - - - -# Adding variables for additional sources - - -# We're using C++ -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -############################################################# -# Checks for programs -############################################################# - -# Autoconf inserts "-g -O2" into flags by default -# Set them to be just "-g", but only if the user hasn't already set CXXFLAGS -# We then put "-O2" back in later, assuming optimisations aren't explicitly disabled -: ${CXXFLAGS="-g"} - -# Search for MPI compiler; fail if not found - - - _ax_prog_cxx_mpi_mpi_wanted=yes - if test x"$_ax_prog_cxx_mpi_mpi_wanted" = xyes; then - if test -n "$ac_tool_prefix"; then - for ac_prog in mpic++ mpicxx mpiCC sxmpic++ hcp mpxlC_r mpxlC mpixlcxx_r mpixlcxx mpg++ mpc++ mpCC cmpic++ mpiFCC CCicpc pgCC pathCC sxc++ xlC_r xlC bgxlC_r bgxlC openCC sunCC crayCC aCC CC g++ c++ gpp cxx cc++ cl.exe FCC KCC RCC - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MPICXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$MPICXX"; then - ac_cv_prog_MPICXX="$MPICXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_MPICXX="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -MPICXX=$ac_cv_prog_MPICXX -if test -n "$MPICXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MPICXX" >&5 -$as_echo "$MPICXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$MPICXX" && break - done -fi -if test -z "$MPICXX"; then - ac_ct_MPICXX=$MPICXX - for ac_prog in mpic++ mpicxx mpiCC sxmpic++ hcp mpxlC_r mpxlC mpixlcxx_r mpixlcxx mpg++ mpc++ mpCC cmpic++ mpiFCC CCicpc pgCC pathCC sxc++ xlC_r xlC bgxlC_r bgxlC openCC sunCC crayCC aCC CC g++ c++ gpp cxx cc++ cl.exe FCC KCC RCC -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_MPICXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_MPICXX"; then - ac_cv_prog_ac_ct_MPICXX="$ac_ct_MPICXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_MPICXX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_MPICXX=$ac_cv_prog_ac_ct_MPICXX -if test -n "$ac_ct_MPICXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MPICXX" >&5 -$as_echo "$ac_ct_MPICXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_MPICXX" && break -done - - if test "x$ac_ct_MPICXX" = x; then - MPICXX="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - MPICXX=$ac_ct_MPICXX - fi -fi - - CXX="$MPICXX" - fi - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -if test -z "$CXX"; then - if test -n "$CCC"; then - CXX=$CCC - else - if test -n "$ac_tool_prefix"; then - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CXX"; then - ac_cv_prog_CXX="$CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CXX=$ac_cv_prog_CXX -if test -n "$CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 -$as_echo "$CXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CXX" && break - done -fi -if test -z "$CXX"; then - ac_ct_CXX=$CXX - for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CXX+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CXX"; then - ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CXX="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CXX=$ac_cv_prog_ac_ct_CXX -if test -n "$ac_ct_CXX"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 -$as_echo "$ac_ct_CXX" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CXX" && break -done - - if test "x$ac_ct_CXX" = x; then - CXX="g++" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CXX=$ac_ct_CXX - fi -fi - - fi -fi -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 -$as_echo_n "checking whether the C++ compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C++ compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 -$as_echo_n "checking for C++ compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C++ compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 -$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } -if ${ac_cv_cxx_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_cxx_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 -$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GXX=yes -else - GXX= -fi -ac_test_CXXFLAGS=${CXXFLAGS+set} -ac_save_CXXFLAGS=$CXXFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 -$as_echo_n "checking whether $CXX accepts -g... " >&6; } -if ${ac_cv_prog_cxx_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_cxx_werror_flag=$ac_cxx_werror_flag - ac_cxx_werror_flag=yes - ac_cv_prog_cxx_g=no - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_prog_cxx_g=yes -else - CXXFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - -else - ac_cxx_werror_flag=$ac_save_cxx_werror_flag - CXXFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_prog_cxx_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cxx_werror_flag=$ac_save_cxx_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 -$as_echo "$ac_cv_prog_cxx_g" >&6; } -if test "$ac_test_CXXFLAGS" = set; then - CXXFLAGS=$ac_save_CXXFLAGS -elif test $ac_cv_prog_cxx_g = yes; then - if test "$GXX" = yes; then - CXXFLAGS="-g -O2" - else - CXXFLAGS="-g" - fi -else - if test "$GXX" = yes; then - CXXFLAGS="-O2" - else - CXXFLAGS= - fi -fi -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - - - - -# Check for compiler -# Needs to be split off into an extra macro to ensure right expansion -# order. - - -if test x"$_ax_prog_cxx_mpi_mpi_wanted" = xno; then : - _ax_prog_cxx_mpi_mpi_found=no -else - - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - # test whether MPI_Init() is available - # We do not use AC_SEARCH_LIBS here, as it caches its outcome and - # thus disallows corresponding calls in the other AX_PROG_*_MPI - # macros. - for lib in NONE mpi mpich; do - save_LIBS=$LIBS - if test x"$lib" = xNONE; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for function MPI_Init" >&5 -$as_echo_n "checking for function MPI_Init... " >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for function MPI_Init in -l$lib" >&5 -$as_echo_n "checking for function MPI_Init in -l$lib... " >&6; } - LIBS="-l$lib $LIBS" - fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -extern "C" { void MPI_Init(); } - -int -main () -{ -MPI_Init(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - _ax_prog_cxx_mpi_mpi_found=yes -else - _ax_prog_cxx_mpi_mpi_found=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_ax_prog_cxx_mpi_mpi_found" >&5 -$as_echo "$_ax_prog_cxx_mpi_mpi_found" >&6; } - if test "x$_ax_prog_cxx_mpi_mpi_found" = "xyes"; then - break; - fi - LIBS=$save_LIBS - done - - # Check for header - if test x"$_ax_prog_cxx_mpi_mpi_found" = xyes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mpi.h" >&5 -$as_echo_n "checking for mpi.h... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - _ax_prog_cxx_mpi_mpi_found=no - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -fi - -# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$_ax_prog_cxx_mpi_mpi_found" = xyes; then : - - -$as_echo "#define HAVE_MPI 1" >>confdefs.h - - : - -else - - - as_fn_error $? "*** An MPI compiler is required. You might need to set MPICXX correctly." "$LINENO" 5 - - : - -fi - - - -# Utility programs -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - - -# Set MAKE to gmake if possible, otherwise make -# Extract the first word of "gmake", so it can be a program name with args. -set dummy gmake; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_MAKE+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$MAKE"; then - ac_cv_prog_MAKE="$MAKE" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_MAKE="gmake" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_prog_MAKE" && ac_cv_prog_MAKE="make" -fi -fi -MAKE=$ac_cv_prog_MAKE -if test -n "$MAKE"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAKE" >&5 -$as_echo "$MAKE" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - - - - -ARFLAGS='' -for flag in cruU cru -do - echo 1 > artest1 - ar $flag artest artest1 &&ar $flag artest artest1 - arexit=$? - rm -f artest1 artest - if test $arexit -eq 0 - then - ARFLAGS="$flag" - break; - fi -done -test -z $ARFLAGS && as_fn_error $? "Failed to find suitable flags for ar" "$LINENO" 5 - -# Check for and enable C++14 support -# Error if not supported - ax_cxx_compile_alternatives="14 1y" ax_cxx_compile_cxx14_required=true - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - ac_success=no - - - - if test x$ac_success = xno; then - for alternative in ${ax_cxx_compile_alternatives}; do - for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do - cachevar=`$as_echo "ax_cv_cxx_compile_cxx14_$switch" | $as_tr_sh` - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++14 features with $switch" >&5 -$as_echo_n "checking whether $CXX supports C++14 features with $switch... " >&6; } -if eval \${$cachevar+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_CXX="$CXX" - CXX="$CXX $switch" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -// If the compiler admits that it is not ready for C++11, why torture it? -// Hopefully, this will speed up the test. - -#ifndef __cplusplus - -#error "This is not a C++ compiler" - -#elif __cplusplus < 201103L - -#error "This is not a C++11 compiler" - -#else - -namespace cxx11 -{ - - namespace test_static_assert - { - - template - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); - }; - - } - - namespace test_final_override - { - - struct Base - { - virtual ~Base() {} - virtual void f() {} - }; - - struct Derived : public Base - { - virtual ~Derived() override {} - virtual void f() override {} - }; - - } - - namespace test_double_right_angle_brackets - { - - template < typename T > - struct check {}; - - typedef check single_type; - typedef check> double_type; - typedef check>> triple_type; - typedef check>>> quadruple_type; - - } - - namespace test_decltype - { - - int - f() - { - int a = 1; - decltype(a) b = 2; - return a + b; - } - - } - - namespace test_type_deduction - { - - template < typename T1, typename T2 > - struct is_same - { - static const bool value = false; - }; - - template < typename T > - struct is_same - { - static const bool value = true; - }; - - template < typename T1, typename T2 > - auto - add(T1 a1, T2 a2) -> decltype(a1 + a2) - { - return a1 + a2; - } - - int - test(const int c, volatile int v) - { - static_assert(is_same::value == true, ""); - static_assert(is_same::value == false, ""); - static_assert(is_same::value == false, ""); - auto ac = c; - auto av = v; - auto sumi = ac + av + 'x'; - auto sumf = ac + av + 1.0; - static_assert(is_same::value == true, ""); - static_assert(is_same::value == true, ""); - static_assert(is_same::value == true, ""); - static_assert(is_same::value == false, ""); - static_assert(is_same::value == true, ""); - return (sumf > 0.0) ? sumi : add(c, v); - } - - } - - namespace test_noexcept - { - - int f() { return 0; } - int g() noexcept { return 0; } - - static_assert(noexcept(f()) == false, ""); - static_assert(noexcept(g()) == true, ""); - - } - - namespace test_constexpr - { - - template < typename CharT > - unsigned long constexpr - strlen_c_r(const CharT *const s, const unsigned long acc) noexcept - { - return *s ? strlen_c_r(s + 1, acc + 1) : acc; - } - - template < typename CharT > - unsigned long constexpr - strlen_c(const CharT *const s) noexcept - { - return strlen_c_r(s, 0UL); - } - - static_assert(strlen_c("") == 0UL, ""); - static_assert(strlen_c("1") == 1UL, ""); - static_assert(strlen_c("example") == 7UL, ""); - static_assert(strlen_c("another\0example") == 7UL, ""); - - } - - namespace test_rvalue_references - { - - template < int N > - struct answer - { - static constexpr int value = N; - }; - - answer<1> f(int&) { return answer<1>(); } - answer<2> f(const int&) { return answer<2>(); } - answer<3> f(int&&) { return answer<3>(); } - - void - test() - { - int i = 0; - const int c = 0; - static_assert(decltype(f(i))::value == 1, ""); - static_assert(decltype(f(c))::value == 2, ""); - static_assert(decltype(f(0))::value == 3, ""); - } - - } - - namespace test_uniform_initialization - { - - struct test - { - static const int zero {}; - static const int one {1}; - }; - - static_assert(test::zero == 0, ""); - static_assert(test::one == 1, ""); - - } - - namespace test_lambdas - { - - void - test1() - { - auto lambda1 = [](){}; - auto lambda2 = lambda1; - lambda1(); - lambda2(); - } - - int - test2() - { - auto a = [](int i, int j){ return i + j; }(1, 2); - auto b = []() -> int { return '0'; }(); - auto c = [=](){ return a + b; }(); - auto d = [&](){ return c; }(); - auto e = [a, &b](int x) mutable { - const auto identity = [](int y){ return y; }; - for (auto i = 0; i < a; ++i) - a += b--; - return x + identity(a + b); - }(0); - return a + b + c + d + e; - } - - int - test3() - { - const auto nullary = [](){ return 0; }; - const auto unary = [](int x){ return x; }; - using nullary_t = decltype(nullary); - using unary_t = decltype(unary); - const auto higher1st = [](nullary_t f){ return f(); }; - const auto higher2nd = [unary](nullary_t f1){ - return [unary, f1](unary_t f2){ return f2(unary(f1())); }; - }; - return higher1st(nullary) + higher2nd(nullary)(unary); - } - - } - - namespace test_variadic_templates - { - - template - struct sum; - - template - struct sum - { - static constexpr auto value = N0 + sum::value; - }; - - template <> - struct sum<> - { - static constexpr auto value = 0; - }; - - static_assert(sum<>::value == 0, ""); - static_assert(sum<1>::value == 1, ""); - static_assert(sum<23>::value == 23, ""); - static_assert(sum<1, 2>::value == 3, ""); - static_assert(sum<5, 5, 11>::value == 21, ""); - static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); - - } - - // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae - // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function - // because of this. - namespace test_template_alias_sfinae - { - - struct foo {}; - - template - using member = typename T::member_type; - - template - void func(...) {} - - template - void func(member*) {} - - void test(); - - void test() { func(0); } - - } - -} // namespace cxx11 - -#endif // __cplusplus >= 201103L - - - - -// If the compiler admits that it is not ready for C++14, why torture it? -// Hopefully, this will speed up the test. - -#ifndef __cplusplus - -#error "This is not a C++ compiler" - -#elif __cplusplus < 201402L - -#error "This is not a C++14 compiler" - -#else - -namespace cxx14 -{ - - namespace test_polymorphic_lambdas - { - - int - test() - { - const auto lambda = [](auto&&... args){ - const auto istiny = [](auto x){ - return (sizeof(x) == 1UL) ? 1 : 0; - }; - const int aretiny[] = { istiny(args)... }; - return aretiny[0]; - }; - return lambda(1, 1L, 1.0f, '1'); - } - - } - - namespace test_binary_literals - { - - constexpr auto ivii = 0b0000000000101010; - static_assert(ivii == 42, "wrong value"); - - } - - namespace test_generalized_constexpr - { - - template < typename CharT > - constexpr unsigned long - strlen_c(const CharT *const s) noexcept - { - auto length = 0UL; - for (auto p = s; *p; ++p) - ++length; - return length; - } - - static_assert(strlen_c("") == 0UL, ""); - static_assert(strlen_c("x") == 1UL, ""); - static_assert(strlen_c("test") == 4UL, ""); - static_assert(strlen_c("another\0test") == 7UL, ""); - - } - - namespace test_lambda_init_capture - { - - int - test() - { - auto x = 0; - const auto lambda1 = [a = x](int b){ return a + b; }; - const auto lambda2 = [a = lambda1(x)](){ return a; }; - return lambda2(); - } - - } - - namespace test_digit_separators - { - - constexpr auto ten_million = 100'000'000; - static_assert(ten_million == 100000000, ""); - - } - - namespace test_return_type_deduction - { - - auto f(int& x) { return x; } - decltype(auto) g(int& x) { return x; } - - template < typename T1, typename T2 > - struct is_same - { - static constexpr auto value = false; - }; - - template < typename T > - struct is_same - { - static constexpr auto value = true; - }; - - int - test() - { - auto x = 0; - static_assert(is_same::value, ""); - static_assert(is_same::value, ""); - return x; - } - - } - -} // namespace cxx14 - -#endif // __cplusplus >= 201402L - - - -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - eval $cachevar=yes -else - eval $cachevar=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CXX="$ac_save_CXX" -fi -eval ac_res=\$$cachevar - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" - fi - ac_success=yes - break - fi - done - if test x$ac_success = xyes; then - break - fi - done - fi - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - if test x$ax_cxx_compile_cxx14_required = xtrue; then - if test x$ac_success = xno; then - as_fn_error $? "*** A compiler with support for C++14 language features is required." "$LINENO" 5 - fi - fi - if test x$ac_success = xno; then - HAVE_CXX14=0 - { $as_echo "$as_me:${as_lineno-$LINENO}: No compiler with C++14 support was found" >&5 -$as_echo "$as_me: No compiler with C++14 support was found" >&6;} - else - HAVE_CXX14=1 - -$as_echo "#define HAVE_CXX14 1" >>confdefs.h - - fi - - - -############################################################# -# STD Library functions -############################################################# - -# Checks for libraries. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sqrt in -lm" >&5 -$as_echo_n "checking for sqrt in -lm... " >&6; } -if ${ac_cv_lib_m_sqrt+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lm $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char sqrt (); -int -main () -{ -return sqrt (); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_lib_m_sqrt=yes -else - ac_cv_lib_m_sqrt=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sqrt" >&5 -$as_echo "$ac_cv_lib_m_sqrt" >&6; } -if test "x$ac_cv_lib_m_sqrt" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBM 1 -_ACEOF - - LIBS="-lm $LIBS" - -fi - - -# Checks for header files. -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 -$as_echo_n "checking how to run the C++ preprocessor... " >&6; } -if test -z "$CXXCPP"; then - if ${ac_cv_prog_CXXCPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CXXCPP needs to be expanded - for CXXCPP in "$CXX -E" "/lib/cpp" - do - ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CXXCPP=$CXXCPP - -fi - CXXCPP=$ac_cv_prog_CXXCPP -else - ac_cv_prog_CXXCPP=$CXXCPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 -$as_echo "$CXXCPP" >&6; } -ac_preproc_ok=false -for ac_cxx_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_cxx_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_cxx_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_header in malloc.h stdlib.h string.h strings.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -# Checks for library functions. -for ac_header in stdlib.h -do : - ac_fn_cxx_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" -if test "x$ac_cv_header_stdlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STDLIB_H 1 -_ACEOF - -fi - -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 -$as_echo_n "checking for GNU libc compatible malloc... " >&6; } -if ${ac_cv_func_malloc_0_nonnull+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_malloc_0_nonnull=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#if defined STDC_HEADERS || defined HAVE_STDLIB_H -# include -#else -char *malloc (); -#endif - -int -main () -{ -return ! malloc (0); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_run "$LINENO"; then : - ac_cv_func_malloc_0_nonnull=yes -else - ac_cv_func_malloc_0_nonnull=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 -$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; } -if test $ac_cv_func_malloc_0_nonnull = yes; then : - -$as_echo "#define HAVE_MALLOC 1" >>confdefs.h - -else - $as_echo "#define HAVE_MALLOC 0" >>confdefs.h - - case " $LIBOBJS " in - *" malloc.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS malloc.$ac_objext" - ;; -esac - - -$as_echo "#define malloc rpl_malloc" >>confdefs.h - -fi - - -for ac_header in stdlib.h -do : - ac_fn_cxx_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default" -if test "x$ac_cv_header_stdlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_STDLIB_H 1 -_ACEOF - -fi - -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible realloc" >&5 -$as_echo_n "checking for GNU libc compatible realloc... " >&6; } -if ${ac_cv_func_realloc_0_nonnull+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - ac_cv_func_realloc_0_nonnull=no -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#if defined STDC_HEADERS || defined HAVE_STDLIB_H -# include -#else -char *realloc (); -#endif - -int -main () -{ -return ! realloc (0, 0); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_run "$LINENO"; then : - ac_cv_func_realloc_0_nonnull=yes -else - ac_cv_func_realloc_0_nonnull=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_realloc_0_nonnull" >&5 -$as_echo "$ac_cv_func_realloc_0_nonnull" >&6; } -if test $ac_cv_func_realloc_0_nonnull = yes; then : - -$as_echo "#define HAVE_REALLOC 1" >>confdefs.h - -else - $as_echo "#define HAVE_REALLOC 0" >>confdefs.h - - case " $LIBOBJS " in - *" realloc.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS realloc.$ac_objext" - ;; -esac - - -$as_echo "#define realloc rpl_realloc" >>confdefs.h - -fi - - -for ac_func in vprintf -do : - ac_fn_cxx_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" -if test "x$ac_cv_func_vprintf" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_VPRINTF 1 -_ACEOF - -ac_fn_cxx_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" -if test "x$ac_cv_func__doprnt" = xyes; then : - -$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h - -fi - -fi -done - - - -# Check for OpenMP support -: ${enable_openmp=no} # Disable by default - - OPENMP_CXXFLAGS= - # Check whether --enable-openmp was given. -if test "${enable_openmp+set}" = set; then : - enableval=$enable_openmp; -fi - - if test "$enable_openmp" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CXX option to support OpenMP" >&5 -$as_echo_n "checking for $CXX option to support OpenMP... " >&6; } -if ${ac_cv_prog_cxx_openmp+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#ifndef _OPENMP - choke me -#endif -#include -int main () { return omp_get_num_threads (); } - -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_prog_cxx_openmp='none needed' -else - ac_cv_prog_cxx_openmp='unsupported' - for ac_option in -fopenmp -xopenmp -openmp -mp -omp -qsmp=omp -homp \ - -Popenmp --openmp; do - ac_save_CXXFLAGS=$CXXFLAGS - CXXFLAGS="$CXXFLAGS $ac_option" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#ifndef _OPENMP - choke me -#endif -#include -int main () { return omp_get_num_threads (); } - -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_prog_cxx_openmp=$ac_option -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - CXXFLAGS=$ac_save_CXXFLAGS - if test "$ac_cv_prog_cxx_openmp" != unsupported; then - break - fi - done -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_openmp" >&5 -$as_echo "$ac_cv_prog_cxx_openmp" >&6; } - case $ac_cv_prog_cxx_openmp in #( - "none needed" | unsupported) - ;; #( - *) - OPENMP_CXXFLAGS=$ac_cv_prog_cxx_openmp ;; - esac - fi - - -BOUT_USE_OPENMP=$enable_openmp - -BOUT_OPENMP_SCHEDULE=$with_openmp_schedule - -# Check if we have access to __PRETTY_FUNCTION__ - - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking does C++ compiler support __PRETTY_FUNCTION__" >&5 -$as_echo_n "checking does C++ compiler support __PRETTY_FUNCTION__... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -const char* name = __PRETTY_FUNCTION__; - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - BOUT_HAS_PRETTY_FUNCTION=yes -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - BOUT_HAS_PRETTY_FUNCTION=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - -############################################################# -# Code coverage using gcov -# -# Mutally exclusive with optimisation, therefore needs to come first -# so we can turn off optimisation if coverage is enabled -############################################################# - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - - - - - # allow to override gcov location - -# Check whether --with-gcov was given. -if test "${with_gcov+set}" = set; then : - withval=$with_gcov; _AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov -else - _AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build with code coverage support" >&5 -$as_echo_n "checking whether to build with code coverage support... " >&6; } - # Check whether --enable-code-coverage was given. -if test "${enable_code_coverage+set}" = set; then : - enableval=$enable_code_coverage; -else - enable_code_coverage=no -fi - - - if test x$enable_code_coverage = xyes; then - CODE_COVERAGE_ENABLED_TRUE= - CODE_COVERAGE_ENABLED_FALSE='#' -else - CODE_COVERAGE_ENABLED_TRUE='#' - CODE_COVERAGE_ENABLED_FALSE= -fi - - CODE_COVERAGE_ENABLED=$enable_code_coverage - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_code_coverage" >&5 -$as_echo "$enable_code_coverage" >&6; } - - if test "$enable_code_coverage" = "yes" ; then : - - # check for gcov - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}$_AX_CODE_COVERAGE_GCOV_PROG_WITH", so it can be a program name with args. -set dummy ${ac_tool_prefix}$_AX_CODE_COVERAGE_GCOV_PROG_WITH; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_GCOV+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$GCOV"; then - ac_cv_prog_GCOV="$GCOV" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_GCOV="${ac_tool_prefix}$_AX_CODE_COVERAGE_GCOV_PROG_WITH" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -GCOV=$ac_cv_prog_GCOV -if test -n "$GCOV"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GCOV" >&5 -$as_echo "$GCOV" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_GCOV"; then - ac_ct_GCOV=$GCOV - # Extract the first word of "$_AX_CODE_COVERAGE_GCOV_PROG_WITH", so it can be a program name with args. -set dummy $_AX_CODE_COVERAGE_GCOV_PROG_WITH; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_GCOV+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_GCOV"; then - ac_cv_prog_ac_ct_GCOV="$ac_ct_GCOV" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_GCOV="$_AX_CODE_COVERAGE_GCOV_PROG_WITH" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_GCOV=$ac_cv_prog_ac_ct_GCOV -if test -n "$ac_ct_GCOV"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GCOV" >&5 -$as_echo "$ac_ct_GCOV" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_GCOV" = x; then - GCOV=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - GCOV=$ac_ct_GCOV - fi -else - GCOV="$ac_cv_prog_GCOV" -fi - - if test "X$GCOV" = "X:"; then : - as_fn_error $? "gcov is needed to do coverage" "$LINENO" 5 -fi - - - if test "$GCC" = "no" ; then : - - as_fn_error $? "not compiling with gcc, which is required for gcov code coverage" "$LINENO" 5 - -fi - - # Extract the first word of "lcov", so it can be a program name with args. -set dummy lcov; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_LCOV+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$LCOV"; then - ac_cv_prog_LCOV="$LCOV" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_LCOV="lcov" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -LCOV=$ac_cv_prog_LCOV -if test -n "$LCOV"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LCOV" >&5 -$as_echo "$LCOV" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - # Extract the first word of "genhtml", so it can be a program name with args. -set dummy genhtml; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_GENHTML+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$GENHTML"; then - ac_cv_prog_GENHTML="$GENHTML" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_GENHTML="genhtml" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -GENHTML=$ac_cv_prog_GENHTML -if test -n "$GENHTML"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GENHTML" >&5 -$as_echo "$GENHTML" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - if test -z "$LCOV" ; then : - - as_fn_error $? "To enable code coverage reporting you must have lcov installed" "$LINENO" 5 - -fi - - if test -z "$GENHTML" ; then : - - as_fn_error $? "Could not find genhtml from the lcov package" "$LINENO" 5 - -fi - - CODE_COVERAGE_CPPFLAGS="-DNDEBUG" - CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_LIBS="-lgcov" - CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS" - - - - - - - - CODE_COVERAGE_RULES_CAPTURE=' - @$(LCOV) --quiet $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --no-external --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --no-checksum $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS) - @$(LCOV) --quiet $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS) - -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp - @LANG=C $(GENHTML) --quiet $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --demangle-cpp --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "BOUT++ Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) - @$(LCOV) --summary $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_LCOV_OPTIONS) - @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" -' - CODE_COVERAGE_RULES_CLEAN=' -clean:: code-coverage-clean -distclean:: code-coverage-clean -code-coverage-clean: - -@$(LCOV) --directory $(abs_builddir) -z --quiet - -@$(RM) -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -@find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete -' - -else - - CODE_COVERAGE_RULES_CHECK=' - @echo "Need to reconfigure with --enable-code-coverage" -' - CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK" - CODE_COVERAGE_RULES_CLEAN='' - -fi - -CODE_COVERAGE_RULES=' -# Code coverage -# -# Optional: -# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. -# Multiple directories may be specified, separated by whitespace. -# (Default: $(top_builddir)) -# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated -# by lcov for code coverage. (Default: -# bout-coverage.info) -# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage -# reports to be created. (Default: -# bout-coverage) -# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, -# set to 0 to disable it and leave empty to stay with the default. -# (Default: empty) -# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov -# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) -# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov -# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) -# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov -# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the -# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) -# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov -# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) -# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering -# lcov instance. (Default: empty) -# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov -# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) -# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the -# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) -# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml -# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) -# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore -# -# The generated report will be titled using the $(PACKAGE_NAME) and -# $(PACKAGE_VERSION). In order to add the current git hash to the title, -# use the git-version-gen script, available online. - -# Optional variables -CODE_COVERAGE_DIRECTORY ?= $(abs_builddir) -CODE_COVERAGE_OUTPUT_FILE ?= bout-coverage.info -CODE_COVERAGE_OUTPUT_DIRECTORY ?= bout-coverage -CODE_COVERAGE_BRANCH_COVERAGE ?= -CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ---rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) -CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) -CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" -CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) -CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) -CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= -CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) -CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ -$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ---rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) -CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) -CODE_COVERAGE_IGNORE_PATTERN ?= "*test*/*" - -# Use recursive makes in order to ignore errors during check -check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"' - -# Capture code coverage data -code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"' - -# Hook rule executed before code-coverage-capture, overridable by the user -code-coverage-capture-hook: - -'"$CODE_COVERAGE_RULES_CLEAN"' - -GITIGNOREFILES ?= -GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean -' - - - -if test "x$enable_code_coverage" = "xyes"; then : - - if test "x$enable_optimize"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Code coverage clashes with optimisations, disabling optimisations" >&5 -$as_echo "$as_me: WARNING: Code coverage clashes with optimisations, disabling optimisations" >&2;} - enable_optimize="no" - -fi - COVERAGE_FLAGS="--coverage --no-inline" - LDFLAGS="$LDFLAGS --coverage" - -else - - COVERAGE_FLAGS= - -fi - - -############################################################# -# General Options -############################################################# - -# Always pass -Werror=unknown-warning-option to get Clang to fail on bad -# flags, otherwise they are always appended to the warn_cxxflags variable, -# and Clang warns on them for every compilation unit. -# If this is passed to GCC, it will explode, so the flag must be enabled -# conditionally. -# This check taken from AX_COMPILER_FLAGS_CXXFLAGS -extra_compiler_flags_test="" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -Werror=unknown-warning-option" >&5 -$as_echo_n "checking whether C++ compiler accepts -Werror=unknown-warning-option... " >&6; } -if ${ax_cv_check_cxxflags___Werror_unknown_warning_option+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CXXFLAGS - CXXFLAGS="$CXXFLAGS -Werror=unknown-warning-option" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ax_cv_check_cxxflags___Werror_unknown_warning_option=yes -else - ax_cv_check_cxxflags___Werror_unknown_warning_option=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CXXFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___Werror_unknown_warning_option" >&5 -$as_echo "$ax_cv_check_cxxflags___Werror_unknown_warning_option" >&6; } -if test "x$ax_cv_check_cxxflags___Werror_unknown_warning_option" = xyes; then : - - extra_compiler_flags_test="-Werror=unknown-warning-option" - -else - : -fi - -# A similar check to above, but for Intel. -we is undocumented, but -# the equivalent (?) -diag-error gets accepted by GCC. 10006 is -# "unknown option", and 10148 is the more recent "unknown warning -# option" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts -we10006,10148" >&5 -$as_echo_n "checking whether C++ compiler accepts -we10006,10148... " >&6; } -if ${ax_cv_check_cxxflags___we10006_10148+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CXXFLAGS - CXXFLAGS="$CXXFLAGS -we10006,10148" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - ax_cv_check_cxxflags___we10006_10148=yes -else - ax_cv_check_cxxflags___we10006_10148=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CXXFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cxxflags___we10006_10148" >&5 -$as_echo "$ax_cv_check_cxxflags___we10006_10148" >&6; } -if test "x$ax_cv_check_cxxflags___we10006_10148" = xyes; then : - - extra_compiler_flags_test="-we10006,10148" - -else - : -fi - - -if test "x$enable_warnings" != "xno"; then : - -# Some hopefully sensible default compiler warning flags - - - - - -for flag in -Wall -Wextra -Wnull-dereference ; do - as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags_$extra_compiler_flags_test_$flag" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5 -$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; } -if eval \${$as_CACHEVAR+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CXXFLAGS - CXXFLAGS="$CXXFLAGS $extra_compiler_flags_test $flag" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - eval "$as_CACHEVAR=yes" -else - eval "$as_CACHEVAR=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CXXFLAGS=$ax_check_save_flags -fi -eval ac_res=\$$as_CACHEVAR - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then : - -if ${CXXFLAGS+:} false; then : - - case " $CXXFLAGS " in #( - *" $flag "*) : - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5 - (: CXXFLAGS already contains $flag) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } ;; #( - *) : - - as_fn_append CXXFLAGS " $flag" - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 - (: CXXFLAGS="$CXXFLAGS") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; -esac - -else - - CXXFLAGS=$flag - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 - (: CXXFLAGS="$CXXFLAGS") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - -fi - -else - : -fi - -done - - -# Note we explicitly turn off -Wcast-function-type as PETSc *requires* -# we cast a function to the wrong type in MatFDColoringSetFunction - -# Also note that gcc ignores unknown flags of the form "-Wno-warning" -# for backwards compatibility. Therefore we need to add the positive -# form as an additional flag which it will choke on (if it doesn't -# exist). See: https://gcc.gnu.org/wiki/FAQ#wnowarning - - - - - -for flag in -Wno-cast-function-type ; do - as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags_$extra_compiler_flags_test "-Wcast-function-type"_$flag" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5 -$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; } -if eval \${$as_CACHEVAR+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CXXFLAGS - CXXFLAGS="$CXXFLAGS $extra_compiler_flags_test "-Wcast-function-type" $flag" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - eval "$as_CACHEVAR=yes" -else - eval "$as_CACHEVAR=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CXXFLAGS=$ax_check_save_flags -fi -eval ac_res=\$$as_CACHEVAR - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then : - -if ${CXXFLAGS+:} false; then : - - case " $CXXFLAGS " in #( - *" $flag "*) : - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5 - (: CXXFLAGS already contains $flag) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } ;; #( - *) : - - as_fn_append CXXFLAGS " $flag" - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 - (: CXXFLAGS="$CXXFLAGS") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; -esac - -else - - CXXFLAGS=$flag - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 - (: CXXFLAGS="$CXXFLAGS") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - -fi - -else - : -fi - -done - - - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Compiler warnings disabled" >&5 -$as_echo "$as_me: Compiler warnings disabled" >&6;} - -fi - -OPT_FLAGS="" -enable_checks_def=2 -if test "$enable_debug" != ""; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling all debug options" >&5 -$as_echo "$as_me: Enabling all debug options" >&6;} - enable_checks_def=3 - # use -Og with available, otherwise fall back to -O0 - OPT_FLAGS="-g -O0 -Og -fno-inline -hipa1" - -else - - if test "x$enable_optimize" != "xno"; then : - - case "$enable_optimize" in #( - "default" | "yes" | "") : - { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling default optimisations" >&5 -$as_echo "$as_me: Enabling default optimisations" >&6;} - OPT_FLAGS="-O2" ;; #( - "fast" | "4") : - { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling level 4 optimisations" >&5 -$as_echo "$as_me: Enabling level 4 optimisations" >&6;} - OPT_FLAGS="-Ofast -fno-finite-math-only -march=native -funroll-loops" - enable_checks_def=0 ;; #( - "3") : - { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling level 3 optimisations" >&5 -$as_echo "$as_me: Enabling level 3 optimisations" >&6;} - OPT_FLAGS="-O3 -march=native -funroll-loops" - enable_checks_def=0 ;; #( - "2") : - { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling level 2 optimisations" >&5 -$as_echo "$as_me: Enabling level 2 optimisations" >&6;} - OPT_FLAGS="-O2 -march=native" - enable_checks_def=1 ;; #( - "1" | "0") : - { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling level $enable_optimize optimisations" >&5 -$as_echo "$as_me: Enabling level $enable_optimize optimisations" >&6;} - OPT_FLAGS="-O$enable_optimize" ;; #( - *) : - - as_fn_error $? "unrecognized option: --enable-optimize=$enable_optimize" "$LINENO" 5 - ;; -esac - -else - OPT_FLAGS="" -fi - -fi - -# Append optimisation/debug flags if they work with this compiler - - - - -for flag in $OPT_FLAGS ; do - as_CACHEVAR=`$as_echo "ax_cv_check_cxxflags_$extra_compiler_flags_test_$flag" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C++ compiler accepts $flag" >&5 -$as_echo_n "checking whether C++ compiler accepts $flag... " >&6; } -if eval \${$as_CACHEVAR+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CXXFLAGS - CXXFLAGS="$CXXFLAGS $extra_compiler_flags_test $flag" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - eval "$as_CACHEVAR=yes" -else - eval "$as_CACHEVAR=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CXXFLAGS=$ax_check_save_flags -fi -eval ac_res=\$$as_CACHEVAR - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_CACHEVAR"\" = x"yes"; then : - -if ${CXXFLAGS+:} false; then : - - case " $CXXFLAGS " in #( - *" $flag "*) : - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5 - (: CXXFLAGS already contains $flag) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } ;; #( - *) : - - as_fn_append CXXFLAGS " $flag" - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 - (: CXXFLAGS="$CXXFLAGS") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; -esac - -else - - CXXFLAGS=$flag - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 - (: CXXFLAGS="$CXXFLAGS") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - -fi - -else - : -fi - -done - - -# Disable checks if optimization > 2 is used -if test "x$enable_checks" = "xdefault" ; then : - - enable_checks=$enable_checks_def - -fi - -BOUT_CHECK_LEVEL=0 -if test "x$enable_checks" != "xno" && test "x$enable_checks" != "x0"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Run-time checking enabled" >&5 -$as_echo "$as_me: Run-time checking enabled" >&6;} - case $enable_checks in #( - 1) : - { $as_echo "$as_me:${as_lineno-$LINENO}: -> Level 1 (Basic checking)" >&5 -$as_echo "$as_me: -> Level 1 (Basic checking)" >&6;} - CXXFLAGS="$CXXFLAGS -DCHECK=1" - BOUT_CHECK_LEVEL=1 ;; #( - 3) : - { $as_echo "$as_me:${as_lineno-$LINENO}: -> Level 3 (Full checking)" >&5 -$as_echo "$as_me: -> Level 3 (Full checking)" >&6;} - enable_output_debug=yes - CXXFLAGS="$CXXFLAGS -DCHECK=3" - BOUT_CHECK_LEVEL=3 ;; #( - *) : - { $as_echo "$as_me:${as_lineno-$LINENO}: -> Level 2 (Enhanced checking)" >&5 -$as_echo "$as_me: -> Level 2 (Enhanced checking)" >&6;} - CXXFLAGS="$CXXFLAGS -DCHECK=2" - BOUT_CHECK_LEVEL=2 ;; -esac - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Run-time checking disabled" >&5 -$as_echo "$as_me: Run-time checking disabled" >&6;} - -fi - -BOUT_USE_MSGSTACK=$(test $BOUT_CHECK_LEVEL -gt 1 && echo yes || echo no) -if test "x$enable_msgstack" = "xyes" ; then : - - BOUT_USE_MSGSTACK=yes - -else - - if test "x$enable_msgstack" = "xno" ; then : - - BOUT_USE_MSGSTACK=no - -fi - -fi -if test $BOUT_USE_MSGSTACK = no ; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Stack tracing disabled" >&5 -$as_echo "$as_me: Stack tracing disabled" >&6;} - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Stack tracing enabled" >&5 -$as_echo "$as_me: Stack tracing enabled" >&6;} - -fi - -BOUT_USE_SIGNAL=no -if test "x$enable_signal" != "xno"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Segmentation fault handling enabled" >&5 -$as_echo "$as_me: Segmentation fault handling enabled" >&6;} - BOUT_USE_SIGNAL=yes - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Segmentation fault handling disabled" >&5 -$as_echo "$as_me: Segmentation fault handling disabled" >&6;} - -fi - -BOUT_USE_COLOR=no -if test "x$enable_color" != "xno"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Output coloring enabled" >&5 -$as_echo "$as_me: Output coloring enabled" >&6;} - BOUT_USE_COLOR=yes - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Output coloring disabled" >&5 -$as_echo "$as_me: Output coloring disabled" >&6;} - -fi - -BOUT_USE_TRACK=no -if test "x$enable_track" = "xyes"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Field name tracking enabled" >&5 -$as_echo "$as_me: Field name tracking enabled" >&6;} - BOUT_USE_TRACK=yes - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Field name tracking disabled" >&5 -$as_echo "$as_me: Field name tracking disabled" >&6;} - -fi - -BOUT_USE_SIGFPE=no -if test "x$enable_sigfpe" = "xyes"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Signaling floating point exceptions enabled" >&5 -$as_echo "$as_me: Signaling floating point exceptions enabled" >&6;} - BOUT_USE_SIGFPE=yes - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Signaling floating point exceptions disabled" >&5 -$as_echo "$as_me: Signaling floating point exceptions disabled" >&6;} - -fi - -BOUT_USE_OUTPUT_DEBUG=no -if test "x$enable_output_debug" = "xyes"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Extra debug output enabled" >&5 -$as_echo "$as_me: Extra debug output enabled" >&6;} - BOUT_USE_OUTPUT_DEBUG=yes - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Extra debug output disabled" >&5 -$as_echo "$as_me: Extra debug output disabled" >&6;} - -fi - -BOUT_VERSION=$PACKAGE_VERSION -BOUT_VERSION_MAJOR=$(echo $PACKAGE_VERSION | cut -d. -f1) -BOUT_VERSION_MINOR=$(echo $PACKAGE_VERSION | cut -d. -f2) -BOUT_VERSION_PATCH=$(echo ${PACKAGE_VERSION%-*} | cut -d. -f3) -BOUT_VERSION_TAG=$(echo $PACKAGE_VERSION | cut -d- -f2) - -############################################################# -# Enable Backtrace if possible -############################################################# - -BOUT_USE_BACKTRACE=no -if test "x$enable_backtrace" = "xyes" || test "x$enable_backtrace" = "xmaybe"; then : - - # Extract the first word of "addr2line", so it can be a program name with args. -set dummy addr2line; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$works"; then - ac_cv_prog_works="$works" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_works="yes" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_prog_works" && ac_cv_prog_works="no" -fi -fi -works=$ac_cv_prog_works -if test -n "$works"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $works" >&5 -$as_echo "$works" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - if test $works = yes; then : - - for ac_func in popen backtrace -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - works=yes -else - works=no; break -fi -done - - -fi - - if test $works = yes; then : - - for ac_header in execinfo.h dlfcn.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - works=yes -else - works=no; break -fi - -done - - -fi - - if test $works = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dladdr" >&5 -$as_echo_n "checking for library containing dladdr... " >&6; } -if ${ac_cv_search_dladdr+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dladdr (); -int -main () -{ -return dladdr (); - ; - return 0; -} -_ACEOF -for ac_lib in '' dl; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_cxx_try_link "$LINENO"; then : - ac_cv_search_dladdr=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_dladdr+:} false; then : - break -fi -done -if ${ac_cv_search_dladdr+:} false; then : - -else - ac_cv_search_dladdr=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dladdr" >&5 -$as_echo "$ac_cv_search_dladdr" >&6; } -ac_res=$ac_cv_search_dladdr -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - works=yes -else - works=no; break -fi - - -fi - - if test $works = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Native backtrace enabled" >&5 -$as_echo "$as_me: Native backtrace enabled" >&6;} - BOUT_USE_BACKTRACE=yes - -else - - if test "x$enable_backtrace" = "xyes"; then : - - as_fn_error $? "backtrace requested, but cannot be enabled" "$LINENO" 5 - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Native backtrace disabled" >&5 -$as_echo "$as_me: WARNING: Native backtrace disabled" >&2;} - -fi - -fi - -fi - -if test "x$enable_metric_3d" != "xno"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Using Field3D to store coordinates data, this is experimental." >&5 -$as_echo "$as_me: WARNING: Using Field3D to store coordinates data, this is experimental." >&2;} - BOUT_METRIC_TYPE="3D" - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Using Field2D to store coordinates data" >&5 -$as_echo "$as_me: Using Field2D to store coordinates data" >&6;} - BOUT_METRIC_TYPE="2D" - -fi - -############################################################# -# Build into shared object (pic) -############################################################# - -LIB_TO_BUILD='' -if test "x$enable_shared" = "xyes"; then : - - # compile as position independent code. - # -fpic is apparently faster then -fPIC, but -fPIC works always. - # From a SO comment (https://stackoverflow.com/a/3544211/3384414): - # What's more: I did a little experiment here (on x86_64 - # platform), -fPIC and -fpic appears to have generated the same - # code. It seems they generate a different code only on m68k, - # PowerPC and SPARC. - # Therfore use -fPIC for now - CXXFLAGS="$CXXFLAGS -fPIC" - LIB_TO_BUILD="$LIB_TO_BUILD"' $(BOUT_LIB_PATH)/libbout++.so' - if test "x$enable_static" = "xauto"; then : - - enable_static=no - -fi - SHARED_EXTRA=':' - if test "x$enable_static" = "xno"; then : - - SHARED_EXTRA='$(RM) -f $(BOUT_LIB_PATH)/libbout++.a' - -fi - -else - - if test "x$enable_static" = "xauto"; then : - - enable_static=yes - -fi - -fi - -if test "x$enable_static" = "xyes"; then : - - LIB_TO_BUILD="$LIB_TO_BUILD"' $(BOUT_LIB_PATH)/libbout++.a' - STATIC_EXTRA=':' - # In case we only build static, make sure shared libs are removed - if ! test "x$enable_shared" = "xyes"; then : - - STATIC_EXTRA='$(RM) -f $(BOUT_LIB_PATH)/*.so*' - -fi - -fi - -if test "x$LIB_TO_BUILD" = x ; then : - - as_fn_error $? "Need to enable at least one of static or shared!" "$LINENO" 5 - -fi - -############################################################# -# Git revision number -############################################################# - -rev=`git rev-parse HEAD` -if test $? = 0; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Git revision: $rev" >&5 -$as_echo "$as_me: Git revision: $rev" >&6;} - BOUT_REVISION=$rev - -else - - BOUT_REVISION= - -fi - -############################################################# -# FFT routines -############################################################# - -if test "x$with_fftw" != "xno"; then : - -# Extract the first word of "fftw-wisdom", so it can be a program name with args. -set dummy fftw-wisdom; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_fftw_path+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $fftw_path in - [\\/]* | ?:[\\/]*) - ac_cv_path_fftw_path="$fftw_path" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $with_fftw$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_fftw_path="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_fftw_path" && ac_cv_path_fftw_path="no" - ;; -esac -fi -fftw_path=$ac_cv_path_fftw_path -if test -n "$fftw_path"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $fftw_path" >&5 -$as_echo "$fftw_path" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - if test "x$fftw_path" != "xno"; then : - - fftw_wisdom0=`$as_dirname -- "$fftw_path" || -$as_expr X"$fftw_path" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$fftw_path" : 'X\(//\)[^/]' \| \ - X"$fftw_path" : 'X\(//\)$' \| \ - X"$fftw_path" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$fftw_path" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - fftw_wisdom=`$as_dirname -- "$fftw_wisdom0" || -$as_expr X"$fftw_wisdom0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$fftw_wisdom0" : 'X\(//\)[^/]' \| \ - X"$fftw_wisdom0" : 'X\(//\)$' \| \ - X"$fftw_wisdom0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$fftw_wisdom0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - with_fftw="$with_fftw $fftw_wisdom" - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: FFTW3 requested but fftw-wisdom not found" >&5 -$as_echo "$as_me: FFTW3 requested but fftw-wisdom not found" >&6;} -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftw3.h" >&5 -$as_echo_n "checking for fftw3.h... " >&6; } - - save_CPPFLAGS=$CPPFLAGS - BACH_found=no - - if test ."$with_fftw" != .yes; then : - extra_prefix="$with_fftw" -else - extra_prefix="" -fi - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - BACH_found=yes - - - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - - if test $BACH_found != yes; then : - - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local - do - for path in $search_prefix $search_prefix/include - do - if test -d $path; then : - - CPPFLAGS="$save_CPPFLAGS -I$path" - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - BACH_found=yes - EXTRA_INCS="$EXTRA_INCS -I$path" - - - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi - done - if test .$BACH_found = .yes; then : - break; -fi - done - -fi - - if test $BACH_found = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - CPPFLAGS=$save_CPPFLAGS - -fi - if test .$BACH_found = .yes; then : - -else - as_fn_error $? "FFTW3 requested but header not found" "$LINENO" 5 -fi - - - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libfftw3" >&5 -$as_echo_n "checking for libfftw3... " >&6; } - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - BACL_found=no - - # Try with no extra libraries first - if test ."$with_fftw" = .yes; then : - extra_prefix="" -else - extra_prefix="$with_fftw" -fi - LIBS="$save_LIBS $EXTRA_LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char fftw_plan_dft_r2c_1d(); - -int -main () -{ -return fftw_plan_dft_r2c_1d(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS=$save_LIBS - - # Now try with explicitly linking library - if test $BACL_found != yes; then : - - LIBS="$save_LIBS $EXTRA_LIBS -lfftw3" - if test ."$with_fftw" = .yes; then : - extra_prefix="" -else - extra_prefix="$with_fftw" -fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char fftw_plan_dft_r2c_1d(); - -int -main () -{ -return fftw_plan_dft_r2c_1d(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -lfftw3" - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - - if test $BACL_found != yes; then : - - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local ; do - for path in $search_prefix $search_prefix/lib $search_prefix/lib64 $search_prefix/x86_64-linux-gnu - do - if test -d $path; then : - - LIBS="$save_LIBS $EXTRA_LIBS -lfftw3" - LDFLAGS="$save_LDFLAGS -L$path" - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char fftw_plan_dft_r2c_1d(); - -int -main () -{ -return fftw_plan_dft_r2c_1d(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -L$path -lfftw3" - - - break -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - done - if test .$BACL_found = .yes; then : - break; -fi - done - -fi - - if test $BACL_found = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -fi - - if test $BACL_found = yes; then : - -else - as_fn_error $? "FFTW3 requested but library not found" "$LINENO" 5 -fi - - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS=$save_CPPFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - - BOUT_HAS_FFTW="yes" - -else - -{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuring without FFTW3 is not recommended" >&5 -$as_echo "$as_me: Configuring without FFTW3 is not recommended" >&6;} -BOUT_HAS_FFTW="no" - -fi - -############################################################# -# netCDF support -############################################################# - -NCCONF="" # Configuration script - -BOUT_HAS_NETCDF=no -BOUT_HAS_LEGACY_NETCDF=no -if test "x$with_netcdf" != "xno"; then : - - ########################################## - # Try to find a valid NetCDF configuration - # - # at first, try to find ncconf script - - # Search for NetCDF config scripts, prefer ncxx4-config over nc-config - # Check if the path to the config script has been supplied directly, otherwise - # check the path provided by --with-netcdf, appending "/bin" if need - # be, then check system path - # Set NCCONF to the full path of the found scropt - case `basename $with_netcdf 2> /dev/null` in #( - "ncxx4-config") : - NCCONF=$with_netcdf ;; #( - "nc-config") : - NCCONF=$with_netcdf ;; #( - *) : - for ac_prog in ncxx4-config nc-config -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_NCCONF+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $NCCONF in - [\\/]* | ?:[\\/]*) - ac_cv_path_NCCONF="$NCCONF" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $with_netcdf$PATH_SEPARATOR$with_netcdf/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_NCCONF="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -NCCONF=$ac_cv_path_NCCONF -if test -n "$NCCONF"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NCCONF" >&5 -$as_echo "$NCCONF" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$NCCONF" && break -done - ;; -esac - - ########################################## - # Get configuration - if test "x$NCCONF" != "x" ; then : - - # If we found nc-config rather than ncxx4-config, we need to check if it supports C++ - if test `basename $NCCONF` = 'nc-config'; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $NCCONF has C++4 support" >&5 -$as_echo_n "checking if $NCCONF has C++4 support... " >&6; } - nc_has_cpp4=`$NCCONF --has-c++4` - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $nc_has_cpp4" >&5 -$as_echo "$nc_has_cpp4" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $NCCONF has C++ support" >&5 -$as_echo_n "checking if $NCCONF has C++ support... " >&6; } - nc_has_cpp=`$NCCONF --has-c++` - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $nc_has_cpp" >&5 -$as_echo "$nc_has_cpp" >&6; } - -else - - nc_has_cpp4="yes" - -fi - - NCINC=`$NCCONF --cflags` - EXTRA_INCS="$EXTRA_INCS $NCINC" - if test "x$nc_has_cpp4" = "xyes"; then : - - NCLIB=`$NCCONF --libs` - BOUT_HAS_NETCDF=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: -> NetCDF-4 support enabled" >&5 -$as_echo "$as_me: -> NetCDF-4 support enabled" >&6;} - -else - - # nc-config might not *say* it has C++ support, but we can try anyway - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can compile NetCDF with C++" >&5 -$as_echo_n "checking if we can compile NetCDF with C++... " >&6; } - # Note netcdf_c++ needed - NCLIB=`$NCCONF --libs | sed s/-lnetcdf/-lnetcdf_c++\ -lnetcdf/` - - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CXXFLAGS=$CXXFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - LIBS="$save_LIBS $NCLIB" - LDFLAGS="$save_LDFLAGS $NCLIB" - CXXFLAGS="$save_CXXFLAGS $NCINC" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - -int -main () -{ -NcFile file("foo.nc"); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: -> Legacy NetCDF support enabled" >&5 -$as_echo "$as_me: -> Legacy NetCDF support enabled" >&6;} -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "*** Could not compile NetCDF C++ program! -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CXXFLAGS="$save_CXXFLAGS" - BOUT_HAS_NETCDF=yes - BOUT_HAS_LEGACY_NETCDF=yes - -fi - EXTRA_LIBS="$EXTRA_LIBS $NCLIB" - - file_formats="$file_formats netCDF" - NCPATH="found" - NCFOUND=yes - -else - - # if nc-config / ncxx4-config is not found, try to find library directly - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for netcdfcpp.h" >&5 -$as_echo_n "checking for netcdfcpp.h... " >&6; } - - save_CPPFLAGS=$CPPFLAGS - BACH_found=no - - if test ."$with_netcdf" != .yes; then : - extra_prefix="$with_netcdf" -else - extra_prefix="" -fi - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - BACH_found=yes - - - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - - if test $BACH_found != yes; then : - - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local - do - for path in $search_prefix $search_prefix/include - do - if test -d $path; then : - - CPPFLAGS="$save_CPPFLAGS -I$path" - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - BACH_found=yes - EXTRA_INCS="$EXTRA_INCS -I$path" - - - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi - done - if test .$BACH_found = .yes; then : - break; -fi - done - -fi - - if test $BACH_found = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - CPPFLAGS=$save_CPPFLAGS - -fi - if test .$BACH_found = .yes; then : - - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libnetcdf" >&5 -$as_echo_n "checking for libnetcdf... " >&6; } - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - BACL_found=no - - # Try with no extra libraries first - if test ."$with_netcdf" = .yes; then : - extra_prefix="" -else - extra_prefix="$with_netcdf" -fi - LIBS="$save_LIBS $EXTRA_LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char nc_get_att(); - -int -main () -{ -return nc_get_att(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS=$save_LIBS - - # Now try with explicitly linking library - if test $BACL_found != yes; then : - - LIBS="$save_LIBS $EXTRA_LIBS -lnetcdf" - if test ."$with_netcdf" = .yes; then : - extra_prefix="" -else - extra_prefix="$with_netcdf" -fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char nc_get_att(); - -int -main () -{ -return nc_get_att(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -lnetcdf" - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - - if test $BACL_found != yes; then : - - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local ; do - for path in $search_prefix $search_prefix/lib $search_prefix/lib64 $search_prefix/x86_64-linux-gnu - do - if test -d $path; then : - - LIBS="$save_LIBS $EXTRA_LIBS -lnetcdf" - LDFLAGS="$save_LDFLAGS -L$path" - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char nc_get_att(); - -int -main () -{ -return nc_get_att(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -L$path -lnetcdf" - - - break -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - done - if test .$BACL_found = .yes; then : - break; -fi - done - -fi - - if test $BACL_found = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -fi - - if test $BACL_found = yes; then : - - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libnetcdf_c++" >&5 -$as_echo_n "checking for libnetcdf_c++... " >&6; } - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - BACL_found=no - - # Try with no extra libraries first - if test ."$with_netcdf" = .yes; then : - extra_prefix="" -else - extra_prefix="$with_netcdf" -fi - LIBS="$save_LIBS $EXTRA_LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char nc_close(); - -int -main () -{ -return nc_close(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS=$save_LIBS - - # Now try with explicitly linking library - if test $BACL_found != yes; then : - - LIBS="$save_LIBS $EXTRA_LIBS -lnetcdf_c++" - if test ."$with_netcdf" = .yes; then : - extra_prefix="" -else - extra_prefix="$with_netcdf" -fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char nc_close(); - -int -main () -{ -return nc_close(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -lnetcdf_c++" - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - - if test $BACL_found != yes; then : - - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local ; do - for path in $search_prefix $search_prefix/lib $search_prefix/lib64 $search_prefix/x86_64-linux-gnu - do - if test -d $path; then : - - LIBS="$save_LIBS $EXTRA_LIBS -lnetcdf_c++" - LDFLAGS="$save_LDFLAGS -L$path" - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char nc_close(); - -int -main () -{ -return nc_close(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -L$path -lnetcdf_c++" - - - break -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - done - if test .$BACL_found = .yes; then : - break; -fi - done - -fi - - if test $BACL_found = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -fi - - if test $BACL_found = yes; then : - NCFOUND=yes -else - NCFOUND=no -fi - - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS=$save_CPPFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -else - NCFOUND=no -fi - - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS=$save_CPPFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -else - NCFOUND=no -fi - - - if test "x$NCFOUND" = "xyes"; then : - - file_formats="$file_formats netCDF" - { $as_echo "$as_me:${as_lineno-$LINENO}: -> Legacy NetCDF support enabled" >&5 -$as_echo "$as_me: -> Legacy NetCDF support enabled" >&6;} - NCPATH="found" - BOUT_HAS_NETCDF=yes - BOUT_HAS_LEGACY_NETCDF=yes - -fi - -fi - - if test $with_netcdf && test "x$NCFOUND" != "xyes" ; then : - as_fn_error $? "NetCDF requested but not found" "$LINENO" 5 -fi - if test "x$NCFOUND" != "xyes"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: -> NetCDF support disabled" >&5 -$as_echo "$as_me: -> NetCDF support disabled" >&6;} -fi - -fi - -############################################################# -# Parallel NetCDF support -############################################################# - -PNCPATH="" -if test "$with_pnetcdf" != "no" && test "x$with_pnetcdf" != "x" ; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Searching for Parallel-NetCDF library" >&5 -$as_echo "$as_me: Searching for Parallel-NetCDF library" >&6;} - - if test "x$with_pnetcdf" != "xyes"; then : - - # Given a path to the library - as_ac_File=`$as_echo "ac_cv_file_$with_pnetcdf/include/pnetcdf.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_pnetcdf/include/pnetcdf.h" >&5 -$as_echo_n "checking for $with_pnetcdf/include/pnetcdf.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_pnetcdf/include/pnetcdf.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_pnetcdf/include/pnetcdf.h" | $as_tr_cpp` 1 -_ACEOF -PNCPATH=$with_pnetcdf -else - { $as_echo "$as_me:${as_lineno-$LINENO}: parallel-netcdf not found in given directory" >&5 -$as_echo "$as_me: parallel-netcdf not found in given directory" >&6;} - -fi - - -fi - - # Find the utilities included with pnetcdf - if test "x$PNCPATH" = "x"; then : - - if test "x$with_pnetcdf" = "xyes"; then : - - # Extract the first word of "ncmpidump", so it can be a program name with args. -set dummy ncmpidump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_NCMPIDUMP_PATH+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $NCMPIDUMP_PATH in - [\\/]* | ?:[\\/]*) - ac_cv_path_NCMPIDUMP_PATH="$NCMPIDUMP_PATH" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_NCMPIDUMP_PATH="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -NCMPIDUMP_PATH=$ac_cv_path_NCMPIDUMP_PATH -if test -n "$NCMPIDUMP_PATH"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NCMPIDUMP_PATH" >&5 -$as_echo "$NCMPIDUMP_PATH" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - -else - - # Extract the first word of "ncmpidump", so it can be a program name with args. -set dummy ncmpidump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_NCMPIDUMP_PATH+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $NCMPIDUMP_PATH in - [\\/]* | ?:[\\/]*) - ac_cv_path_NCMPIDUMP_PATH="$NCMPIDUMP_PATH" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_NCMPIDUMP_PATH="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_NCMPIDUMP_PATH" && ac_cv_path_NCMPIDUMP_PATH="$with_pnetcdf$PATH_SEPARATOR$PATH" - ;; -esac -fi -NCMPIDUMP_PATH=$ac_cv_path_NCMPIDUMP_PATH -if test -n "$NCMPIDUMP_PATH"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NCMPIDUMP_PATH" >&5 -$as_echo "$NCMPIDUMP_PATH" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - -fi - if test "$NCMPIDUMP_PATH" != ""; then : - - as_ac_File=`$as_echo "ac_cv_file_$NCMPIDUMP_PATH/../include/pnetcdf.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $NCMPIDUMP_PATH/../include/pnetcdf.h" >&5 -$as_echo_n "checking for $NCMPIDUMP_PATH/../include/pnetcdf.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$NCMPIDUMP_PATH/../include/pnetcdf.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$NCMPIDUMP_PATH/../include/pnetcdf.h" | $as_tr_cpp` 1 -_ACEOF -PNCPATH=$NCMPIDUMP_PATH/../ -fi - - -fi - -fi - - if test "x$PNCPATH" != "x"; then : - - as_ac_File=`$as_echo "ac_cv_file_$path/lib/libpnetcdf.a" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $path/lib/libpnetcdf.a" >&5 -$as_echo_n "checking for $path/lib/libpnetcdf.a... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$path/lib/libpnetcdf.a"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$path/lib/libpnetcdf.a" | $as_tr_cpp` 1 -_ACEOF -PNCPATHLIB='lib' -else - as_ac_File=`$as_echo "ac_cv_file_$path/lib64/libpnetcdf.a" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $path/lib64/libpnetcdf.a" >&5 -$as_echo_n "checking for $path/lib64/libpnetcdf.a... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$path/lib64/libpnetcdf.a"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$path/lib64/libpnetcdf.a" | $as_tr_cpp` 1 -_ACEOF -PNCPATHLIB='lib64' -else - PNCPATH='' -fi - -fi - - -fi - - if test "x$PNCPATH" = "x" && test "x$with_pnetcdf" != "x"; then : - - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "*** Parallel-NetCDF requested but not found -See \`config.log' for more details" "$LINENO" 5; } - -fi - -fi - -if test "x$PNCPATH" = "x"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Parallel-NetCDF support disabled" >&5 -$as_echo "$as_me: Parallel-NetCDF support disabled" >&6;} - -else - - # Set a compile-time flag - CXXFLAGS="$CXXFLAGS -DPNCDF" - EXTRA_INCS="$EXTRA_INCS -I$PNCPATH/include" - EXTRA_LIBS="$EXTRA_LIBS -L$PNCPATH/$PNCPATHLIB -lpnetcdf" - - file_formats="$file_formats Parallel-NetCDF" - { $as_echo "$as_me:${as_lineno-$LINENO}: Parallel-NetCDF support enabled" >&5 -$as_echo "$as_me: Parallel-NetCDF support enabled" >&6;} - -fi - -############################################################# -# Check file formats -############################################################# - -if test "x$file_formats" = "x"; then : - - as_fn_error $? "*** At least one file format must be supported" "$LINENO" 5 - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Supported file formats:$file_formats" >&5 -$as_echo "$as_me: Supported file formats:$file_formats" >&6;} - -fi - -############################################################# -# LAPACK routines (Used for tri- and band-diagonal solvers) -############################################################# - -BOUT_HAS_LAPACK="no" -if test "x$with_lapack" != "xno"; then : - - if test "x$with_lapack" = "xguess" || test "x$with_lapack" = "x" ; then : - lapack_path="" -else - if test "x$with_lapack" != xyes; then : - lapack_path=$with_lapack - with_lapack=yes -else - lapack_path="" -fi - -fi - - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libblas" >&5 -$as_echo_n "checking for libblas... " >&6; } - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - BACL_found=no - - # Try with no extra libraries first - if test ."$lapack_path" = .yes; then : - extra_prefix="" -else - extra_prefix="$lapack_path" -fi - LIBS="$save_LIBS $EXTRA_LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char zgemm_(); - -int -main () -{ -return zgemm_(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS=$save_LIBS - - # Now try with explicitly linking library - if test $BACL_found != yes; then : - - LIBS="$save_LIBS $EXTRA_LIBS -lblas" - if test ."$lapack_path" = .yes; then : - extra_prefix="" -else - extra_prefix="$lapack_path" -fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char zgemm_(); - -int -main () -{ -return zgemm_(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -lblas" - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - - if test $BACL_found != yes; then : - - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local ; do - for path in $search_prefix $search_prefix/lib $search_prefix/lib64 $search_prefix/x86_64-linux-gnu - do - if test -d $path; then : - - LIBS="$save_LIBS $EXTRA_LIBS -lblas" - LDFLAGS="$save_LDFLAGS -L$path" - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char zgemm_(); - -int -main () -{ -return zgemm_(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -L$path -lblas" - - - break -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - done - if test .$BACL_found = .yes; then : - break; -fi - done - -fi - - if test $BACL_found = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -fi - - if test $BACL_found = yes; then : - BOUT_HAS_BLAS=yes -else - if test "x$with_lapack" = "xyes"; then : - as_fn_error $? "LAPACK requested but couldn't find BLAS" "$LINENO" 5 -fi -fi - - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS=$save_CPPFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for liblapack" >&5 -$as_echo_n "checking for liblapack... " >&6; } - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - BACL_found=no - - # Try with no extra libraries first - if test ."$lapack_path" = .yes; then : - extra_prefix="" -else - extra_prefix="$lapack_path" -fi - LIBS="$save_LIBS $EXTRA_LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char zgbsv_(); - -int -main () -{ -return zgbsv_(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS=$save_LIBS - - # Now try with explicitly linking library - if test $BACL_found != yes; then : - - LIBS="$save_LIBS $EXTRA_LIBS -llapack" - if test ."$lapack_path" = .yes; then : - extra_prefix="" -else - extra_prefix="$lapack_path" -fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char zgbsv_(); - -int -main () -{ -return zgbsv_(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -llapack" - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - - if test $BACL_found != yes; then : - - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local ; do - for path in $search_prefix $search_prefix/lib $search_prefix/lib64 $search_prefix/x86_64-linux-gnu - do - if test -d $path; then : - - LIBS="$save_LIBS $EXTRA_LIBS -llapack" - LDFLAGS="$save_LDFLAGS -L$path" - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char zgbsv_(); - -int -main () -{ -return zgbsv_(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -L$path -llapack" - - - break -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - done - if test .$BACL_found = .yes; then : - break; -fi - done - -fi - - if test $BACL_found = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -fi - - if test $BACL_found = yes; then : - BOUT_HAS_LAPACK=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: Using LAPACK" >&5 -$as_echo "$as_me: Using LAPACK" >&6;} - -else - if test "x$with_lapack" = "xyes"; then : - as_fn_error $? "LAPACK requested but not found" "$LINENO" 5 -fi -fi - - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS=$save_CPPFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - -fi - -############################################################# -# PETSc library -############################################################# - - - - - - - - -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PKG_CONFIG=$ac_cv_path_PKG_CONFIG -if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_path_PKG_CONFIG"; then - ac_pt_PKG_CONFIG=$PKG_CONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $ac_pt_PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG -if test -n "$ac_pt_PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -$as_echo "$ac_pt_PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_pt_PKG_CONFIG" = x; then - PKG_CONFIG="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - PKG_CONFIG=$ac_pt_PKG_CONFIG - fi -else - PKG_CONFIG="$ac_cv_path_PKG_CONFIG" -fi - -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=0.9.0 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 -$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - PKG_CONFIG="" - fi -fi -if test "x$with_petsc" != "x" && test "$with_petsc" != "no"; then : - - -# Supplying an argument to "--with-petsc" only works if PETSC_ARCH -# *should* be empty. If it should be non-empty, THIS WILL NOT WORK - if test "$with_petsc" != "yes"; then : - - PETSC_DIR="$with_petsc" - PETSC_ARCH= - -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: Using PETSC_DIR=$PETSC_DIR, PETSC_ARCH=$PETSC_ARCH" >&5 -$as_echo "$as_me: Using PETSC_DIR=$PETSC_DIR, PETSC_ARCH=$PETSC_ARCH" >&6;} - -# Define a macro for a nice error message that preserves the -# formatting. Use like: -# -# PETSC_ERROR_MESSAGE -# -# with no identation - - -# PETSc changed the location of the conf directory in 3.5, so we -# need to check both locations -# If we find nether, try to fall back to pkg-conf - PETSC_PKGCONF=no - as_ac_File=`$as_echo "ac_cv_file_$PETSC_DIR/$PETSC_ARCH/conf" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $PETSC_DIR/$PETSC_ARCH/conf" >&5 -$as_echo_n "checking for $PETSC_DIR/$PETSC_ARCH/conf... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$PETSC_DIR/$PETSC_ARCH/conf"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - - PETSC_CONFDIR=${PETSC_DIR}/conf - -else - - as_ac_File=`$as_echo "ac_cv_file_$PETSC_DIR/$PETSC_ARCH/lib/petsc/conf" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $PETSC_DIR/$PETSC_ARCH/lib/petsc/conf" >&5 -$as_echo_n "checking for $PETSC_DIR/$PETSC_ARCH/lib/petsc/conf... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$PETSC_DIR/$PETSC_ARCH/lib/petsc/conf"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - - PETSC_CONFDIR=${PETSC_DIR}/lib/petsc/conf - -else - - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PETSc >= 3.4.0 " >&5 -$as_echo_n "checking for PETSc >= 3.4.0 ... " >&6; } - -if test -n "$PETSC_CFLAGS"; then - pkg_cv_PETSC_CFLAGS="$PETSC_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"PETSc >= 3.4.0 \""; } >&5 - ($PKG_CONFIG --exists --print-errors "PETSc >= 3.4.0 ") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_PETSC_CFLAGS=`$PKG_CONFIG --cflags "PETSc >= 3.4.0 " 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$PETSC_LIBS"; then - pkg_cv_PETSC_LIBS="$PETSC_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"PETSc >= 3.4.0 \""; } >&5 - ($PKG_CONFIG --exists --print-errors "PETSc >= 3.4.0 ") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_PETSC_LIBS=`$PKG_CONFIG --libs "PETSc >= 3.4.0 " 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - PETSC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "PETSc >= 3.4.0 " 2>&1` - else - PETSC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "PETSc >= 3.4.0 " 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$PETSC_PKG_ERRORS" >&5 - - - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for petsc >= 3.4.0 " >&5 -$as_echo_n "checking for petsc >= 3.4.0 ... " >&6; } - -if test -n "$PETSC_CFLAGS"; then - pkg_cv_PETSC_CFLAGS="$PETSC_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"petsc >= 3.4.0 \""; } >&5 - ($PKG_CONFIG --exists --print-errors "petsc >= 3.4.0 ") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_PETSC_CFLAGS=`$PKG_CONFIG --cflags "petsc >= 3.4.0 " 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$PETSC_LIBS"; then - pkg_cv_PETSC_LIBS="$PETSC_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"petsc >= 3.4.0 \""; } >&5 - ($PKG_CONFIG --exists --print-errors "petsc >= 3.4.0 ") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_PETSC_LIBS=`$PKG_CONFIG --libs "petsc >= 3.4.0 " 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - PETSC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "petsc >= 3.4.0 " 2>&1` - else - PETSC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "petsc >= 3.4.0 " 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$PETSC_PKG_ERRORS" >&5 - - - as_fn_error $? "--with-petsc was specified but could not find PETSc distribution. - You may need to specify PETSC_DIR and PETSC_ARCH like so: - --with-petsc PETSC_DIR=\$PETSC_DIR PETSC_ARCH=\$PETSC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#petsc - " "$LINENO" 5 - -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - - as_fn_error $? "--with-petsc was specified but could not find PETSc distribution. - You may need to specify PETSC_DIR and PETSC_ARCH like so: - --with-petsc PETSC_DIR=\$PETSC_DIR PETSC_ARCH=\$PETSC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#petsc - " "$LINENO" 5 - -else - PETSC_CFLAGS=$pkg_cv_PETSC_CFLAGS - PETSC_LIBS=$pkg_cv_PETSC_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - PETSC_PKGCONF=yes -fi - -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for petsc >= 3.4.0 " >&5 -$as_echo_n "checking for petsc >= 3.4.0 ... " >&6; } - -if test -n "$PETSC_CFLAGS"; then - pkg_cv_PETSC_CFLAGS="$PETSC_CFLAGS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"petsc >= 3.4.0 \""; } >&5 - ($PKG_CONFIG --exists --print-errors "petsc >= 3.4.0 ") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_PETSC_CFLAGS=`$PKG_CONFIG --cflags "petsc >= 3.4.0 " 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi -if test -n "$PETSC_LIBS"; then - pkg_cv_PETSC_LIBS="$PETSC_LIBS" - elif test -n "$PKG_CONFIG"; then - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"petsc >= 3.4.0 \""; } >&5 - ($PKG_CONFIG --exists --print-errors "petsc >= 3.4.0 ") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_PETSC_LIBS=`$PKG_CONFIG --libs "petsc >= 3.4.0 " 2>/dev/null` - test "x$?" != "x0" && pkg_failed=yes -else - pkg_failed=yes -fi - else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - PETSC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "petsc >= 3.4.0 " 2>&1` - else - PETSC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "petsc >= 3.4.0 " 2>&1` - fi - # Put the nasty error message in config.log where it belongs - echo "$PETSC_PKG_ERRORS" >&5 - - - as_fn_error $? "--with-petsc was specified but could not find PETSc distribution. - You may need to specify PETSC_DIR and PETSC_ARCH like so: - --with-petsc PETSC_DIR=\$PETSC_DIR PETSC_ARCH=\$PETSC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#petsc - " "$LINENO" 5 - -elif test $pkg_failed = untried; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - - as_fn_error $? "--with-petsc was specified but could not find PETSc distribution. - You may need to specify PETSC_DIR and PETSC_ARCH like so: - --with-petsc PETSC_DIR=\$PETSC_DIR PETSC_ARCH=\$PETSC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#petsc - " "$LINENO" 5 - -else - PETSC_CFLAGS=$pkg_cv_PETSC_CFLAGS - PETSC_LIBS=$pkg_cv_PETSC_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - PETSC_PKGCONF=yes -fi - -else - PETSC_CFLAGS=$pkg_cv_PETSC_CFLAGS - PETSC_LIBS=$pkg_cv_PETSC_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - PETSC_PKGCONF=yes -fi - -fi - - -fi - - - if test $PETSC_PKGCONF = no ; then : - -# We've found an installation, need to check we can use it. First we -# need to be able to check the version number, for which we need -# petscverion.h - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I$PETSC_DIR/include" - ac_fn_cxx_check_header_mongrel "$LINENO" "petscversion.h" "ac_cv_header_petscversion_h" "$ac_includes_default" -if test "x$ac_cv_header_petscversion_h" = xyes; then : - FOUND_PETSC_HEADER=yes -else - FOUND_PETSC_HEADER=no - -fi - - - -# This is a terrible hack for some Linux distributions (Fedora) that -# install PETSc in a non-supported fashion. This is really the fault -# of PETSc for their weird method of installation - if test $FOUND_PETSC_HEADER = no; then : - - as_ac_File=`$as_echo "ac_cv_file_${PETSC_CONFDIR}/petscvariables" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${PETSC_CONFDIR}/petscvariables" >&5 -$as_echo_n "checking for ${PETSC_CONFDIR}/petscvariables... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "${PETSC_CONFDIR}/petscvariables"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -else - - as_fn_error $? "Unable to find either petscversion.h or petscvariables - You may need to specify PETSC_DIR and PETSC_ARCH like so: - --with-petsc PETSC_DIR=\$PETSC_DIR PETSC_ARCH=\$PETSC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#petsc - " "$LINENO" 5 - -fi - - -# This relies on the assumption that PETSC_ARCH is empty - PETSC_CC_INCLUDES=$(grep ^PETSC_CC_INCLUDES ${PETSC_CONFDIR}/petscvariables | cut -d= -f 2-) - - { $as_echo "$as_me:${as_lineno-$LINENO}: Looking for petscverion.h using $PETSC_CC_INCLUDES from ${PETSC_CONFDIR}/petscvariables" >&5 -$as_echo "$as_me: Looking for petscverion.h using $PETSC_CC_INCLUDES from ${PETSC_CONFDIR}/petscvariables" >&6;} - - # This is the cache variable set by the previous call to - # AC_CHECK_HEADER. We need to unset it so we can call the macro - # again, but now with different CPPFLAGS - { ac_cv_header_petscversion_h=; unset ac_cv_header_petscversion_h;} - - CPPFLAGS="$CPPFLAGS $PETSC_CC_INCLUDES" - ac_fn_cxx_check_header_mongrel "$LINENO" "petscversion.h" "ac_cv_header_petscversion_h" "$ac_includes_default" -if test "x$ac_cv_header_petscversion_h" = xyes; then : - -else - - as_fn_error $? "Couldn't find or include petscversion.h. - You may need to specify PETSC_DIR and PETSC_ARCH like so: - --with-petsc PETSC_DIR=\$PETSC_DIR PETSC_ARCH=\$PETSC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#petsc - " "$LINENO" 5 - -fi - - - -fi - -# Now we have the header we want, we can check the version number - { $as_echo "$as_me:${as_lineno-$LINENO}: checking PETSc is at least 3.4.0" >&5 -$as_echo_n "checking PETSc is at least 3.4.0... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - #if PETSC_VERSION_GE(3, 4, 0) - yes - #endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : - PETSC_VERSION_OK="yes" -else - PETSC_VERSION_OK="no" -fi -rm -f conftest* - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PETSC_VERSION_OK" >&5 -$as_echo "$PETSC_VERSION_OK" >&6; } - CPPFLAGS="$save_CPPFLAGS" - - if test $PETSC_VERSION_OK = no; then : - - as_fn_error $? "PETSc version must be at least 3.4.0" "$LINENO" 5 - -fi - -# Check if PETSc was compiled with SUNDIALS - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I$PETSC_DIR/$PETSC_ARCH/include" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking PETSc has SUNDIALS support" >&5 -$as_echo_n "checking PETSc has SUNDIALS support... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - #ifdef PETSC_HAVE_SUNDIALS - yes - #endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : - PETSC_HAS_SUNDIALS="yes" -else - PETSC_HAS_SUNDIALS="no" -fi -rm -f conftest* - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PETSC_HAS_SUNDIALS" >&5 -$as_echo "$PETSC_HAS_SUNDIALS" >&6; } - CPPFLAGS="$save_CPPFLAGS" - - if test "$PETSC_HAS_SUNDIALS" = "yes"; then : - - CXXFLAGS="$CXXFLAGS -DPETSC_HAS_SUNDIALS " - -fi - - # Set the line to be included in the make.conf file - PETSC_MAKE_INCLUDE="include ${PETSC_CONFDIR}/variables" - - BOUT_HAS_PETSC="yes" - - EXTRA_INCS="$EXTRA_INCS \$(PETSC_CC_INCLUDES)" - EXTRA_LIBS="$EXTRA_LIBS \$(PETSC_LIB)" - -else - - # Check if PETSc was compiled with SUNDIALS - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $PETSC_CFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking PETSc has SUNDIALS support" >&5 -$as_echo_n "checking PETSc has SUNDIALS support... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - #ifdef PETSC_HAVE_SUNDIALS - yes - #endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : - PETSC_HAS_SUNDIALS="yes" -else - PETSC_HAS_SUNDIALS="no" -fi -rm -f conftest* - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PETSC_HAS_SUNDIALS" >&5 -$as_echo "$PETSC_HAS_SUNDIALS" >&6; } - CPPFLAGS="$save_CPPFLAGS" - - if test "$PETSC_HAS_SUNDIALS" = "yes"; then : - - CXXFLAGS="$CXXFLAGS -DPETSC_HAS_SUNDIALS " - -fi - PETSC_MAKE_INCLUDE= - BOUT_HAS_PETSC="yes" - - EXTRA_INCS="$EXTRA_INCS $PETSC_CFLAGS" - EXTRA_LIBS="$PETSC_LIBS $EXTRA_LIBS" - -fi - -else - - PETSC_MAKE_INCLUDE= - BOUT_HAS_PETSC="no" - PETSC_HAS_SUNDIALS="no" - -fi - -############################################################# -# SLEPc library -############################################################# - -if test "x$with_slepc" != "x" && test "$with_slepc" != "no"; then : - - - if test $BOUT_HAS_PETSC = "no"; then : - - as_fn_error $? "--with-slepc specified, but no PETSc detected. Please reconfigure and specify --with-petsc - You may need to specify PETSC_DIR and PETSC_ARCH like so: - --with-petsc PETSC_DIR=\$PETSC_DIR PETSC_ARCH=\$PETSC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#petsc - " "$LINENO" 5 - -fi - -# Supplying an argument to "--with-slepc" only works if SLEPC_ARCH -# *should* be empty. If it should be non-empty, THIS WILL NOT WORK - if test "$with_slepc" != "yes"; then : - - SLEPC_DIR="$with_slepc" - SLEPC_ARCH= - -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: Using SLEPC_DIR=$SLEPC_DIR, SLEPC_ARCH=$SLEPC_ARCH" >&5 -$as_echo "$as_me: Using SLEPC_DIR=$SLEPC_DIR, SLEPC_ARCH=$SLEPC_ARCH" >&6;} - -# Define a macro for a nice error message that preserves the -# formatting. Use like: -# -# SLEPC_ERROR_MESSAGE -# -# with no identation - - -# Slepc changed the location of the conf directory in 3.5, so we -# need to check both locations - as_ac_File=`$as_echo "ac_cv_file_$SLEPC_DIR/$SLEPC_ARCH/conf" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $SLEPC_DIR/$SLEPC_ARCH/conf" >&5 -$as_echo_n "checking for $SLEPC_DIR/$SLEPC_ARCH/conf... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$SLEPC_DIR/$SLEPC_ARCH/conf"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - - SLEPC_CONFDIR=${SLEPC_DIR}/conf - -else - - as_ac_File=`$as_echo "ac_cv_file_$SLEPC_DIR/$SLEPC_ARCH/lib/slepc/conf" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $SLEPC_DIR/$SLEPC_ARCH/lib/slepc/conf" >&5 -$as_echo_n "checking for $SLEPC_DIR/$SLEPC_ARCH/lib/slepc/conf... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$SLEPC_DIR/$SLEPC_ARCH/lib/slepc/conf"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - - SLEPC_CONFDIR=${SLEPC_DIR}/lib/slepc/conf - -else - - as_fn_error $? "--with-slepc was specified but could not find Slepc distribution. - You may need to specify SLEPC_DIR and SLEPC_ARCH like so: - --with-slepc SLEPC_DIR=\$SLEPC_DIR SLEPC_ARCH=\$SLEPC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#slepc - " "$LINENO" 5 - -fi - - -fi - - -# We've found an installation, need to check we can use it. First we -# need to be able to check the version number, for which we need -# slepcverion.h - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I$SLEPC_DIR/include" - ac_fn_cxx_check_header_mongrel "$LINENO" "slepcversion.h" "ac_cv_header_slepcversion_h" "$ac_includes_default" -if test "x$ac_cv_header_slepcversion_h" = xyes; then : - FOUND_SLEPC_HEADER=yes -else - FOUND_SLEPC_HEADER=no - -fi - - - -# This is a terrible hack for some Linux distributions (Fedora) that -# install Slepc in a non-supported fashion. This is really the fault -# of Slepc for their weird method of installation - if test $FOUND_SLEPC_HEADER = no; then : - - as_ac_File=`$as_echo "ac_cv_file_${SLEPC_CONFDIR}/slepc_variables" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${SLEPC_CONFDIR}/slepc_variables" >&5 -$as_echo_n "checking for ${SLEPC_CONFDIR}/slepc_variables... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "${SLEPC_CONFDIR}/slepc_variables"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -else - - as_fn_error $? "Unable to find either slepcversion.h or slepc_variables - You may need to specify SLEPC_DIR and SLEPC_ARCH like so: - --with-slepc SLEPC_DIR=\$SLEPC_DIR SLEPC_ARCH=\$SLEPC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#slepc - " "$LINENO" 5 - -fi - - -# This relies on the assumption that SLEPC_ARCH is empty - SLEPC_CC_INCLUDES=$(grep ^SLEPC_CC_INCLUDES ${SLEPC_CONFDIR}/slepc_variables | cut -d= -f 2-) - - { $as_echo "$as_me:${as_lineno-$LINENO}: Looking for slepcverion.h using $SLEPC_CC_INCLUDES from ${SLEPC_CONFDIR}/slepc_variables" >&5 -$as_echo "$as_me: Looking for slepcverion.h using $SLEPC_CC_INCLUDES from ${SLEPC_CONFDIR}/slepc_variables" >&6;} - - # This is the cache variable set by the previous call to - # AC_CHECK_HEADER. We need to unset it so we can call the macro - # again, but now with different CPPFLAGS - { ac_cv_header_slepcversion_h=; unset ac_cv_header_slepcversion_h;} - - CPPFLAGS="$CPPFLAGS $SLEPC_CC_INCLUDES" - ac_fn_cxx_check_header_mongrel "$LINENO" "slepcversion.h" "ac_cv_header_slepcversion_h" "$ac_includes_default" -if test "x$ac_cv_header_slepcversion_h" = xyes; then : - -else - - as_fn_error $? "Couldn't find or include slepcversion.h. - You may need to specify SLEPC_DIR and SLEPC_ARCH like so: - --with-slepc SLEPC_DIR=\$SLEPC_DIR SLEPC_ARCH=\$SLEPC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#slepc - " "$LINENO" 5 - -fi - - - -fi - -# Now we have the header we want, we can check the version number - { $as_echo "$as_me:${as_lineno-$LINENO}: checking Slepc is at least 3.4.0" >&5 -$as_echo_n "checking Slepc is at least 3.4.0... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - #if SLEPC_VERSION_GE(3, 4, 0) - yes - #endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "yes" >/dev/null 2>&1; then : - SLEPC_VERSION_OK="yes" -else - SLEPC_VERSION_OK="no" -fi -rm -f conftest* - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SLEPC_VERSION_OK" >&5 -$as_echo "$SLEPC_VERSION_OK" >&6; } - CPPFLAGS="$save_CPPFLAGS" - - if test $SLEPC_VERSION_OK = no; then : - - as_fn_error $? "Slepc version must be at least 3.4.0" "$LINENO" 5 - -fi - -# Check if Slepc was compiled with SUNDIALS - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I$SLEPC_DIR/$SLEPC_ARCH/include" - - # Set the line to be included in the make.conf file - SLEPC_MAKE_INCLUDE="include ${SLEPC_CONFDIR}/slepc_variables" - - BOUT_HAS_SLEPC="yes" - - EXTRA_INCS="$EXTRA_INCS \$(SLEPC_INCLUDE)" - EXTRA_LIBS="$EXTRA_LIBS \$(SLEPC_LIB)" - - -else - - SLEPC_MAKE_INCLUDE= - BOUT_HAS_SLEPC="no" - -fi - -############################################################# -# Solver choice: SUNDIALS' IDA, SUNDIALS' CVODE, PVODE -############################################################# - -BOUT_HAS_SUNDIALS=no -if test "x$with_sundials" != "x" && test "x$with_sundials" != "xno"; then : - - - # Now follows a few different checks for the version of SUNDIALS. - # We need the sundials_config.h header, which comes with all the - # versions we care about - - # If we've been given a path, look in there first - if test "x$with_sundials" != "xyes"; then : - - as_ac_File=`$as_echo "ac_cv_file_$with_sundials/include/sundials/sundials_config.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_sundials/include/sundials/sundials_config.h" >&5 -$as_echo_n "checking for $with_sundials/include/sundials/sundials_config.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_sundials/include/sundials/sundials_config.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - SUNDIALS_INC=$with_sundials/include -else - SUNDIALS_INC="" -fi - - -fi - - # If we've got one, add the include dir to the preprocessor flags - save_CPPFLAGS=$CPPFLAGS - if test "x$SUNDIALS_INC" != "x"; then : - CPPFLAGS="-I$SUNDIALS_INC" -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SUNDIALS config header" >&5 -$as_echo_n "checking for SUNDIALS config header... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include "sundials/sundials_config.h" - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "*** Could not determine SUNDIALS version -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SUNDIALS minor version" >&5 -$as_echo_n "checking for SUNDIALS minor version... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include "sundials/sundials_config.h" - #ifdef SUNDIALS_PACKAGE_VERSION - SUNDIALS_PACKAGE_VERSION - #endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "^ *\"? *[12]\.[0-5]\." >/dev/null 2>&1; then : - sundials_minor_ver="too low" -else - sundials_minor_ver=ok -fi -rm -f conftest* - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_minor_ver" >&5 -$as_echo "$sundials_minor_ver" >&6; } - - CPPFLAGS=$save_CPPFLAGS - - if test "$sundials_minor_ver" = "too low"; then : - - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "*** Unsupported SUNDIALS version: Requires at least 2.6 -See \`config.log' for more details" "$LINENO" 5; } - -fi - - # Set both IDA and CVODE if not set already - if test "x$with_ida" = "x"; then : - - with_ida=$with_sundials - -fi - - if test "x$with_cvode" = "x"; then : - - with_cvode=$with_sundials - -fi - - if test "x$with_arkode" = "x"; then : - - with_arkode=$with_sundials - -fi - BOUT_HAS_SUNDIALS=yes - -fi - -if test "x$with_ida" != "x" && test "x$with_ida" != "xno"; then : - - - - with_module=$with_ida - module_upper=IDA - - { $as_echo "$as_me:${as_lineno-$LINENO}: Searching for SUNDIALS $module_upper library" >&5 -$as_echo "$as_me: Searching for SUNDIALS $module_upper library" >&6;} - if test "$with_module" = "yes"; then : - - # No path specified. Try using sundials-config - # Extract the first word of "sundials-config", so it can be a program name with args. -set dummy sundials-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_sundials_config+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $sundials_config in - [\\/]* | ?:[\\/]*) - ac_cv_path_sundials_config="$sundials_config" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $with_sundials$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_sundials_config="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_sundials_config" && ac_cv_path_sundials_config="no" - ;; -esac -fi -sundials_config=$ac_cv_path_sundials_config -if test -n "$sundials_config"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_config" >&5 -$as_echo "$sundials_config" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test "x$sundials_config" != xno; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Found sundials-config, this means your version of SUNDIALS is < 2.6, and probably won't work" >&5 -$as_echo "$as_me: WARNING: Found sundials-config, this means your version of SUNDIALS is < 2.6, and probably won't work" >&2;} - sundials_module_includes=`$sundials_config -m ida -t p -l c -s cppflags` - sundials_module_libs=`$sundials_config -m ida -t p -l c -s libs` - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No sundials-config available, no path given, will try compiling with $module_upper anyway" >&5 -$as_echo "$as_me: WARNING: No sundials-config available, no path given, will try compiling with $module_upper anyway" >&2;} - sundials_module_includes="" - # Need to link to libsundials_ida, libsundials_cvode or libsundials_arkode - sundials_module_libs="-lsundials_ida -lsundials_nvecparallel $SUNDIALS_EXTRA_LIBS" - -fi - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can compile with SUNDIALS $module_upper" >&5 -$as_echo_n "checking if we can compile with SUNDIALS $module_upper... " >&6; } - save_LIBS=$LIBS - save_CXXFLAGS=$CXXFLAGS - LIBS="$save_LIBS $sundials_module_libs" - CXXFLAGS="$save_CXXFLAGS $sundials_module_includes" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - #include - extern void foo(N_Vector); - - -int -main () -{ -IDACreate(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - sundials_config_worked=yes -else - sundials_config_worked=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_config_worked" >&5 -$as_echo "$sundials_config_worked" >&6; } - if test $sundials_config_worked = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Using SUNDIALS $module_upper solver" >&5 -$as_echo "$as_me: Using SUNDIALS $module_upper solver" >&6;} - -else - - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Could not compile SUNDIALS $module_upper program, check your SUNDIALS version -See \`config.log' for more details" "$LINENO" 5; } - -fi - LIBS=$save_LIBS - CXXFLAGS="$save_CXXFLAGS" - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -else - - # Specified with path - { $as_echo "$as_me:${as_lineno-$LINENO}: Checking for $module_upper header files" >&5 -$as_echo "$as_me: Checking for $module_upper header files" >&6;} - - # Check whether user supplied path to $module_upper install dir... - as_ac_File=`$as_echo "ac_cv_file_$with_module/include/ida/ida.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/ida/ida.h" >&5 -$as_echo_n "checking for $with_module/include/ida/ida.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/ida/ida.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/ida/ida.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/ida/ida_spgmr.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/ida/ida_spgmr.h" >&5 -$as_echo_n "checking for $with_module/include/ida/ida_spgmr.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/ida/ida_spgmr.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/ida/ida_spgmr.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/ida/ida_bbdpre.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/ida/ida_bbdpre.h" >&5 -$as_echo_n "checking for $with_module/include/ida/ida_bbdpre.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/ida/ida_bbdpre.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/ida/ida_bbdpre.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/nvector/nvector_parallel.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/nvector/nvector_parallel.h" >&5 -$as_echo_n "checking for $with_module/include/nvector/nvector_parallel.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/nvector/nvector_parallel.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/nvector/nvector_parallel.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/sundials/sundials_types.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/sundials/sundials_types.h" >&5 -$as_echo_n "checking for $with_module/include/sundials/sundials_types.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/sundials/sundials_types.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/sundials/sundials_types.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi - - if test $sundials_module_includes_found = no; then : - - # ...or path to $module_upper lib dir - as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/ida/ida.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/ida/ida.h" >&5 -$as_echo_n "checking for $with_module/../include/ida/ida.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/ida/ida.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/ida/ida.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/ida/ida_spgmr.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/ida/ida_spgmr.h" >&5 -$as_echo_n "checking for $with_module/../include/ida/ida_spgmr.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/ida/ida_spgmr.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/ida/ida_spgmr.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/ida/ida_bbdpre.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/ida/ida_bbdpre.h" >&5 -$as_echo_n "checking for $with_module/../include/ida/ida_bbdpre.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/ida/ida_bbdpre.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/ida/ida_bbdpre.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/nvector/nvector_parallel.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/nvector/nvector_parallel.h" >&5 -$as_echo_n "checking for $with_module/../include/nvector/nvector_parallel.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/nvector/nvector_parallel.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/nvector/nvector_parallel.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/sundials/sundials_types.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/sundials/sundials_types.h" >&5 -$as_echo_n "checking for $with_module/../include/sundials/sundials_types.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/sundials/sundials_types.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/sundials/sundials_types.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi - - -fi - - if test $sundials_module_includes_found = no; then : - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Missing one or more $module_upper headers -See \`config.log' for more details" "$LINENO" 5; } -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: Found $module_upper include path: $sundials_module_includes_path" >&5 -$as_echo "$as_me: Found $module_upper include path: $sundials_module_includes_path" >&6;} - - # We've now got the include directory and can specify what libraries we need - sundials_module_includes="-I$sundials_module_includes_path" - sundials_module_libs="-lsundials_ida -lsundials_nvecparallel $SUNDIALS_EXTRA_LIBS" - - # Try compiling something simple with a few different common paths - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - for sundials_module_lib_path in "$with_module" "$with_module/lib" "$with_module/lib64" - do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if SUNDIALS $module_upper library path is $sundials_module_lib_path" >&5 -$as_echo_n "checking if SUNDIALS $module_upper library path is $sundials_module_lib_path... " >&6; } - LIBS="$save_LIBS $sundials_module_libs" - LDFLAGS="$save_LDFLAGS -L$sundials_module_lib_path" - CPPFLAGS="$save_CPPFLAGS $sundials_module_includes" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - #include - extern void foo(N_Vector); - - -int -main () -{ -IDACreate(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - sundials_module_lib_path_found=yes -else - sundials_module_lib_path_found=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_module_lib_path_found" >&5 -$as_echo "$sundials_module_lib_path_found" >&6; } - if test "x$sundials_module_lib_path_found" = "xyes"; then : - break -fi - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS="$save_CPPFLAGS" - done - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - SUNDIALS_MODULE_LDFLAGS="-L$sundials_module_lib_path" - -fi - - if test "x$sundials_module_lib_path_found" = "xno"; then : - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Cannot compile $module_upper program -See \`config.log' for more details" "$LINENO" 5; } -fi - - # Compile in the $module_upper solver - { $as_echo "$as_me:${as_lineno-$LINENO}: => $module_upper solver enabled" >&5 -$as_echo "$as_me: => $module_upper solver enabled" >&6;} - EXTRA_LIBS="$EXTRA_LIBS $SUNDIALS_MODULE_LDFLAGS $sundials_module_libs" - EXTRA_INCS="$EXTRA_INCS $sundials_module_includes" - - eval "`$as_echo "BOUT_HAS_$module_upper" | $as_tr_sh`=yes" - eval "`$as_echo "${module_upper}LIBS" | $as_tr_sh`=\"\$SUNDIALS_MODULE_LDFLAGS \$sundials_module_libs\"" - eval "`$as_echo "${module_upper}INCS" | $as_tr_sh`=\"\$sundials_module_includes\"" - - -fi - -if test "x$with_cvode" != "x" && test "x$with_cvode" != "xno"; then : - - - - with_module=$with_cvode - module_upper=CVODE - - { $as_echo "$as_me:${as_lineno-$LINENO}: Searching for SUNDIALS $module_upper library" >&5 -$as_echo "$as_me: Searching for SUNDIALS $module_upper library" >&6;} - if test "$with_module" = "yes"; then : - - # No path specified. Try using sundials-config - # Extract the first word of "sundials-config", so it can be a program name with args. -set dummy sundials-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_sundials_config+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $sundials_config in - [\\/]* | ?:[\\/]*) - ac_cv_path_sundials_config="$sundials_config" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $with_sundials$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_sundials_config="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_sundials_config" && ac_cv_path_sundials_config="no" - ;; -esac -fi -sundials_config=$ac_cv_path_sundials_config -if test -n "$sundials_config"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_config" >&5 -$as_echo "$sundials_config" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test "x$sundials_config" != xno; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Found sundials-config, this means your version of SUNDIALS is < 2.6, and probably won't work" >&5 -$as_echo "$as_me: WARNING: Found sundials-config, this means your version of SUNDIALS is < 2.6, and probably won't work" >&2;} - sundials_module_includes=`$sundials_config -m cvode -t p -l c -s cppflags` - sundials_module_libs=`$sundials_config -m cvode -t p -l c -s libs` - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No sundials-config available, no path given, will try compiling with $module_upper anyway" >&5 -$as_echo "$as_me: WARNING: No sundials-config available, no path given, will try compiling with $module_upper anyway" >&2;} - sundials_module_includes="" - # Need to link to libsundials_ida, libsundials_cvode or libsundials_arkode - sundials_module_libs="-lsundials_cvode -lsundials_nvecparallel $SUNDIALS_EXTRA_LIBS" - -fi - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can compile with SUNDIALS $module_upper" >&5 -$as_echo_n "checking if we can compile with SUNDIALS $module_upper... " >&6; } - save_LIBS=$LIBS - save_CXXFLAGS=$CXXFLAGS - LIBS="$save_LIBS $sundials_module_libs" - CXXFLAGS="$save_CXXFLAGS $sundials_module_includes" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - #include - extern void foo(N_Vector); - - -int -main () -{ - - #if SUNDIALS_VERSION_MAJOR >= 4 - CVodeCreate(0); - #else - CVodeCreate(0, 0); - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - sundials_config_worked=yes -else - sundials_config_worked=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_config_worked" >&5 -$as_echo "$sundials_config_worked" >&6; } - if test $sundials_config_worked = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Using SUNDIALS $module_upper solver" >&5 -$as_echo "$as_me: Using SUNDIALS $module_upper solver" >&6;} - -else - - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Could not compile SUNDIALS $module_upper program, check your SUNDIALS version -See \`config.log' for more details" "$LINENO" 5; } - -fi - LIBS=$save_LIBS - CXXFLAGS="$save_CXXFLAGS" - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -else - - # Specified with path - { $as_echo "$as_me:${as_lineno-$LINENO}: Checking for $module_upper header files" >&5 -$as_echo "$as_me: Checking for $module_upper header files" >&6;} - - # Check whether user supplied path to $module_upper install dir... - as_ac_File=`$as_echo "ac_cv_file_$with_module/include/cvode/cvode.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/cvode/cvode.h" >&5 -$as_echo_n "checking for $with_module/include/cvode/cvode.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/cvode/cvode.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/cvode/cvode.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/cvode/cvode_spgmr.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/cvode/cvode_spgmr.h" >&5 -$as_echo_n "checking for $with_module/include/cvode/cvode_spgmr.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/cvode/cvode_spgmr.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/cvode/cvode_spgmr.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/cvode/cvode_bbdpre.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/cvode/cvode_bbdpre.h" >&5 -$as_echo_n "checking for $with_module/include/cvode/cvode_bbdpre.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/cvode/cvode_bbdpre.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/cvode/cvode_bbdpre.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/nvector/nvector_parallel.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/nvector/nvector_parallel.h" >&5 -$as_echo_n "checking for $with_module/include/nvector/nvector_parallel.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/nvector/nvector_parallel.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/nvector/nvector_parallel.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/sundials/sundials_types.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/sundials/sundials_types.h" >&5 -$as_echo_n "checking for $with_module/include/sundials/sundials_types.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/sundials/sundials_types.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/sundials/sundials_types.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi - - if test $sundials_module_includes_found = no; then : - - # ...or path to $module_upper lib dir - as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/cvode/cvode.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/cvode/cvode.h" >&5 -$as_echo_n "checking for $with_module/../include/cvode/cvode.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/cvode/cvode.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/cvode/cvode.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/cvode/cvode_spgmr.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/cvode/cvode_spgmr.h" >&5 -$as_echo_n "checking for $with_module/../include/cvode/cvode_spgmr.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/cvode/cvode_spgmr.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/cvode/cvode_spgmr.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/cvode/cvode_bbdpre.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/cvode/cvode_bbdpre.h" >&5 -$as_echo_n "checking for $with_module/../include/cvode/cvode_bbdpre.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/cvode/cvode_bbdpre.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/cvode/cvode_bbdpre.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/nvector/nvector_parallel.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/nvector/nvector_parallel.h" >&5 -$as_echo_n "checking for $with_module/../include/nvector/nvector_parallel.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/nvector/nvector_parallel.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/nvector/nvector_parallel.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/sundials/sundials_types.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/sundials/sundials_types.h" >&5 -$as_echo_n "checking for $with_module/../include/sundials/sundials_types.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/sundials/sundials_types.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/sundials/sundials_types.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi - - -fi - - if test $sundials_module_includes_found = no; then : - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Missing one or more $module_upper headers -See \`config.log' for more details" "$LINENO" 5; } -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: Found $module_upper include path: $sundials_module_includes_path" >&5 -$as_echo "$as_me: Found $module_upper include path: $sundials_module_includes_path" >&6;} - - # We've now got the include directory and can specify what libraries we need - sundials_module_includes="-I$sundials_module_includes_path" - sundials_module_libs="-lsundials_cvode -lsundials_nvecparallel $SUNDIALS_EXTRA_LIBS" - - # Try compiling something simple with a few different common paths - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - for sundials_module_lib_path in "$with_module" "$with_module/lib" "$with_module/lib64" - do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if SUNDIALS $module_upper library path is $sundials_module_lib_path" >&5 -$as_echo_n "checking if SUNDIALS $module_upper library path is $sundials_module_lib_path... " >&6; } - LIBS="$save_LIBS $sundials_module_libs" - LDFLAGS="$save_LDFLAGS -L$sundials_module_lib_path" - CPPFLAGS="$save_CPPFLAGS $sundials_module_includes" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - #include - extern void foo(N_Vector); - - -int -main () -{ - - #if SUNDIALS_VERSION_MAJOR >= 4 - CVodeCreate(0); - #else - CVodeCreate(0, 0); - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - sundials_module_lib_path_found=yes -else - sundials_module_lib_path_found=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_module_lib_path_found" >&5 -$as_echo "$sundials_module_lib_path_found" >&6; } - if test "x$sundials_module_lib_path_found" = "xyes"; then : - break -fi - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS="$save_CPPFLAGS" - done - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - SUNDIALS_MODULE_LDFLAGS="-L$sundials_module_lib_path" - -fi - - if test "x$sundials_module_lib_path_found" = "xno"; then : - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Cannot compile $module_upper program -See \`config.log' for more details" "$LINENO" 5; } -fi - - # Compile in the $module_upper solver - { $as_echo "$as_me:${as_lineno-$LINENO}: => $module_upper solver enabled" >&5 -$as_echo "$as_me: => $module_upper solver enabled" >&6;} - EXTRA_LIBS="$EXTRA_LIBS $SUNDIALS_MODULE_LDFLAGS $sundials_module_libs" - EXTRA_INCS="$EXTRA_INCS $sundials_module_includes" - - eval "`$as_echo "BOUT_HAS_$module_upper" | $as_tr_sh`=yes" - eval "`$as_echo "${module_upper}LIBS" | $as_tr_sh`=\"\$SUNDIALS_MODULE_LDFLAGS \$sundials_module_libs\"" - eval "`$as_echo "${module_upper}INCS" | $as_tr_sh`=\"\$sundials_module_includes\"" - - -fi - -if test "x$with_arkode" != "x" && test "x$with_arkode" != "xno"; then : - - - - with_module=$with_arkode - module_upper=ARKODE - - { $as_echo "$as_me:${as_lineno-$LINENO}: Searching for SUNDIALS $module_upper library" >&5 -$as_echo "$as_me: Searching for SUNDIALS $module_upper library" >&6;} - if test "$with_module" = "yes"; then : - - # No path specified. Try using sundials-config - # Extract the first word of "sundials-config", so it can be a program name with args. -set dummy sundials-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_sundials_config+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $sundials_config in - [\\/]* | ?:[\\/]*) - ac_cv_path_sundials_config="$sundials_config" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $with_sundials$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_sundials_config="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_sundials_config" && ac_cv_path_sundials_config="no" - ;; -esac -fi -sundials_config=$ac_cv_path_sundials_config -if test -n "$sundials_config"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_config" >&5 -$as_echo "$sundials_config" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - if test "x$sundials_config" != xno; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Found sundials-config, this means your version of SUNDIALS is < 2.6, and probably won't work" >&5 -$as_echo "$as_me: WARNING: Found sundials-config, this means your version of SUNDIALS is < 2.6, and probably won't work" >&2;} - sundials_module_includes=`$sundials_config -m arkode -t p -l c -s cppflags` - sundials_module_libs=`$sundials_config -m arkode -t p -l c -s libs` - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No sundials-config available, no path given, will try compiling with $module_upper anyway" >&5 -$as_echo "$as_me: WARNING: No sundials-config available, no path given, will try compiling with $module_upper anyway" >&2;} - sundials_module_includes="" - # Need to link to libsundials_ida, libsundials_cvode or libsundials_arkode - sundials_module_libs="-lsundials_arkode -lsundials_nvecparallel $SUNDIALS_EXTRA_LIBS" - -fi - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can compile with SUNDIALS $module_upper" >&5 -$as_echo_n "checking if we can compile with SUNDIALS $module_upper... " >&6; } - save_LIBS=$LIBS - save_CXXFLAGS=$CXXFLAGS - LIBS="$save_LIBS $sundials_module_libs" - CXXFLAGS="$save_CXXFLAGS $sundials_module_includes" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - #if SUNDIALS_VERSION_MAJOR >= 4 - #include - #else - #include - #endif - extern void foo(N_Vector); - - -int -main () -{ - - #if SUNDIALS_VERSION_MAJOR >= 4 - ARKStepCreate(0, 0, 0, 0); - #else - ARKodeCreate(); - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - sundials_config_worked=yes -else - sundials_config_worked=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_config_worked" >&5 -$as_echo "$sundials_config_worked" >&6; } - if test $sundials_config_worked = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Using SUNDIALS $module_upper solver" >&5 -$as_echo "$as_me: Using SUNDIALS $module_upper solver" >&6;} - -else - - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Could not compile SUNDIALS $module_upper program, check your SUNDIALS version -See \`config.log' for more details" "$LINENO" 5; } - -fi - LIBS=$save_LIBS - CXXFLAGS="$save_CXXFLAGS" - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -else - - # Specified with path - { $as_echo "$as_me:${as_lineno-$LINENO}: Checking for $module_upper header files" >&5 -$as_echo "$as_me: Checking for $module_upper header files" >&6;} - - # Check whether user supplied path to $module_upper install dir... - as_ac_File=`$as_echo "ac_cv_file_$with_module/include/arkode/arkode.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/arkode/arkode.h" >&5 -$as_echo_n "checking for $with_module/include/arkode/arkode.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/arkode/arkode.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/arkode/arkode.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/arkode/arkode_spgmr.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/arkode/arkode_spgmr.h" >&5 -$as_echo_n "checking for $with_module/include/arkode/arkode_spgmr.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/arkode/arkode_spgmr.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/arkode/arkode_spgmr.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/arkode/arkode_bbdpre.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/arkode/arkode_bbdpre.h" >&5 -$as_echo_n "checking for $with_module/include/arkode/arkode_bbdpre.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/arkode/arkode_bbdpre.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/arkode/arkode_bbdpre.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/nvector/nvector_parallel.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/nvector/nvector_parallel.h" >&5 -$as_echo_n "checking for $with_module/include/nvector/nvector_parallel.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/nvector/nvector_parallel.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/nvector/nvector_parallel.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/include/sundials/sundials_types.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/include/sundials/sundials_types.h" >&5 -$as_echo_n "checking for $with_module/include/sundials/sundials_types.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/include/sundials/sundials_types.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/include/sundials/sundials_types.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include -else - sundials_module_includes_found=no -fi - - if test $sundials_module_includes_found = no; then : - - # ...or path to $module_upper lib dir - as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/arkode/arkode.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/arkode/arkode.h" >&5 -$as_echo_n "checking for $with_module/../include/arkode/arkode.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/arkode/arkode.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/arkode/arkode.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/arkode/arkode_spgmr.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/arkode/arkode_spgmr.h" >&5 -$as_echo_n "checking for $with_module/../include/arkode/arkode_spgmr.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/arkode/arkode_spgmr.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/arkode/arkode_spgmr.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/arkode/arkode_bbdpre.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/arkode/arkode_bbdpre.h" >&5 -$as_echo_n "checking for $with_module/../include/arkode/arkode_bbdpre.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/arkode/arkode_bbdpre.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/arkode/arkode_bbdpre.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/nvector/nvector_parallel.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/nvector/nvector_parallel.h" >&5 -$as_echo_n "checking for $with_module/../include/nvector/nvector_parallel.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/nvector/nvector_parallel.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/nvector/nvector_parallel.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi -as_ac_File=`$as_echo "ac_cv_file_$with_module/../include/sundials/sundials_types.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $with_module/../include/sundials/sundials_types.h" >&5 -$as_echo_n "checking for $with_module/../include/sundials/sundials_types.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$with_module/../include/sundials/sundials_types.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - -cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$with_module/../include/sundials/sundials_types.h" | $as_tr_cpp` 1 -_ACEOF -sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include -else - sundials_module_includes_found=no -fi - - -fi - - if test $sundials_module_includes_found = no; then : - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Missing one or more $module_upper headers -See \`config.log' for more details" "$LINENO" 5; } -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: Found $module_upper include path: $sundials_module_includes_path" >&5 -$as_echo "$as_me: Found $module_upper include path: $sundials_module_includes_path" >&6;} - - # We've now got the include directory and can specify what libraries we need - sundials_module_includes="-I$sundials_module_includes_path" - sundials_module_libs="-lsundials_arkode -lsundials_nvecparallel $SUNDIALS_EXTRA_LIBS" - - # Try compiling something simple with a few different common paths - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - for sundials_module_lib_path in "$with_module" "$with_module/lib" "$with_module/lib64" - do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if SUNDIALS $module_upper library path is $sundials_module_lib_path" >&5 -$as_echo_n "checking if SUNDIALS $module_upper library path is $sundials_module_lib_path... " >&6; } - LIBS="$save_LIBS $sundials_module_libs" - LDFLAGS="$save_LDFLAGS -L$sundials_module_lib_path" - CPPFLAGS="$save_CPPFLAGS $sundials_module_includes" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include - #if SUNDIALS_VERSION_MAJOR >= 4 - #include - #else - #include - #endif - extern void foo(N_Vector); - - -int -main () -{ - - #if SUNDIALS_VERSION_MAJOR >= 4 - ARKStepCreate(0, 0, 0, 0); - #else - ARKodeCreate(); - #endif - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - sundials_module_lib_path_found=yes -else - sundials_module_lib_path_found=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_module_lib_path_found" >&5 -$as_echo "$sundials_module_lib_path_found" >&6; } - if test "x$sundials_module_lib_path_found" = "xyes"; then : - break -fi - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS="$save_CPPFLAGS" - done - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - - SUNDIALS_MODULE_LDFLAGS="-L$sundials_module_lib_path" - -fi - - if test "x$sundials_module_lib_path_found" = "xno"; then : - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "Cannot compile $module_upper program -See \`config.log' for more details" "$LINENO" 5; } -fi - - # Compile in the $module_upper solver - { $as_echo "$as_me:${as_lineno-$LINENO}: => $module_upper solver enabled" >&5 -$as_echo "$as_me: => $module_upper solver enabled" >&6;} - EXTRA_LIBS="$EXTRA_LIBS $SUNDIALS_MODULE_LDFLAGS $sundials_module_libs" - EXTRA_INCS="$EXTRA_INCS $sundials_module_includes" - - eval "`$as_echo "BOUT_HAS_$module_upper" | $as_tr_sh`=yes" - eval "`$as_echo "${module_upper}LIBS" | $as_tr_sh`=\"\$SUNDIALS_MODULE_LDFLAGS \$sundials_module_libs\"" - eval "`$as_echo "${module_upper}INCS" | $as_tr_sh`=\"\$sundials_module_includes\"" - - -fi - -############################################################# -# HYPRE -############################################################# - -BOUT_HAS_HYPRE="no" -if test "$with_hypre" != "no"; then : - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for HYPRE.h" >&5 -$as_echo_n "checking for HYPRE.h... " >&6; } - - save_CPPFLAGS=$CPPFLAGS - BACH_found=no - - if test ."$with_hypre - " != .yes; then : - extra_prefix="$with_hypre - " -else - extra_prefix="" -fi - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - BACH_found=yes - - - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - - if test $BACH_found != yes; then : - - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local - do - for path in $search_prefix $search_prefix/include - do - if test -d $path; then : - - CPPFLAGS="$save_CPPFLAGS -I$path" - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - BACH_found=yes - EXTRA_INCS="$EXTRA_INCS -I$path" - - - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi - done - if test .$BACH_found = .yes; then : - break; -fi - done - -fi - - if test $BACH_found = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - CPPFLAGS=$save_CPPFLAGS - -fi - if test .$BACH_found = .yes; then : - - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libHYPRE" >&5 -$as_echo_n "checking for libHYPRE... " >&6; } - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - BACL_found=no - - # Try with no extra libraries first - if test ."$with_hypre" = .yes; then : - extra_prefix="" -else - extra_prefix="$with_hypre" -fi - LIBS="$save_LIBS $EXTRA_LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char HYPRE_IJVectorCreate(); - -int -main () -{ -return HYPRE_IJVectorCreate(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS=$save_LIBS - - # Now try with explicitly linking library - if test $BACL_found != yes; then : - - LIBS="$save_LIBS $EXTRA_LIBS -lHYPRE" - if test ."$with_hypre" = .yes; then : - extra_prefix="" -else - extra_prefix="$with_hypre" -fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char HYPRE_IJVectorCreate(); - -int -main () -{ -return HYPRE_IJVectorCreate(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -lHYPRE" - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - - if test $BACL_found != yes; then : - - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local ; do - for path in $search_prefix $search_prefix/lib $search_prefix/lib64 $search_prefix/x86_64-linux-gnu - do - if test -d $path; then : - - LIBS="$save_LIBS $EXTRA_LIBS -lHYPRE" - LDFLAGS="$save_LDFLAGS -L$path" - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char HYPRE_IJVectorCreate(); - -int -main () -{ -return HYPRE_IJVectorCreate(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -L$path -lHYPRE" - - - break -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - done - if test .$BACL_found = .yes; then : - break; -fi - done - -fi - - if test $BACL_found = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -fi - - if test $BACL_found = yes; then : - - BOUT_HAS_HYPRE="yes" - -else - as_fn_error $? "HYPRE requested but not found" "$LINENO" 5 -fi - - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS=$save_CPPFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -else - as_fn_error $? "HYPRE requested but not found" "$LINENO" 5 -fi - - -fi - -############################################################# -# Scorep setup -############################################################# - -BOUT_HAS_SCOREP="no" -if test "$with_scorep" != "no"; then : - - - if test "$with_scorep" != "yes"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Searching for Scorep executable in $with_scorep" >&5 -$as_echo "$as_me: Searching for Scorep executable in $with_scorep" >&6;} - # Extract the first word of "scorep", so it can be a program name with args. -set dummy scorep; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SCOREPPATH+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $SCOREPPATH in - [\\/]* | ?:[\\/]*) - ac_cv_path_SCOREPPATH="$SCOREPPATH" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $with_scorep -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_SCOREPPATH="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -SCOREPPATH=$ac_cv_path_SCOREPPATH -if test -n "$SCOREPPATH"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SCOREPPATH" >&5 -$as_echo "$SCOREPPATH" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Searching for Scorep executable" >&5 -$as_echo "$as_me: Searching for Scorep executable" >&6;} - # Extract the first word of "scorep", so it can be a program name with args. -set dummy scorep; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_SCOREPPATH+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $SCOREPPATH in - [\\/]* | ?:[\\/]*) - ac_cv_path_SCOREPPATH="$SCOREPPATH" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_SCOREPPATH="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -SCOREPPATH=$ac_cv_path_SCOREPPATH -if test -n "$SCOREPPATH"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SCOREPPATH" >&5 -$as_echo "$SCOREPPATH" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - -fi - - if test "$SCOREPPATH" = ""; then : - - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "*** Scorep requested, but executable not found. -Please supply the path using --with-scorep=/path/to/scorep -See \`config.log' for more details" "$LINENO" 5; } - -else - - CXX="$SCOREPPATH --user --nocompiler $CXX" - BOUT_HAS_SCOREP="yes" - { $as_echo "$as_me:${as_lineno-$LINENO}: Scorep support enabled" >&5 -$as_echo "$as_me: Scorep support enabled" >&6;} - -fi - - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Scorep support disabled" >&5 -$as_echo "$as_me: Scorep support disabled" >&6;} - -fi - -############################################################# -# Check for mpark.variant -############################################################# - -if test ".$with_system_mpark" = "no"; then : - - SYSTEM_HAS_MPARK=no - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mpark.variant" >&5 -$as_echo_n "checking for mpark.variant... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - #include "mpark/variant.hpp" - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SYSTEM_HAS_MPARK=yes -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SYSTEM_HAS_MPARK=no - if test "$with_system_mpark" = "yes"; then : - - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "*** System mpark.variant not found - but requested to use -See \`config.log' for more details" "$LINENO" 5; } - -fi -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi - -if test "$SYSTEM_HAS_MPARK" = "yes"; then : - - MPARK_VARIANT_INCLUDE_PATH= - MPARK_INCLUDE= - OWN_MPARK= - -else - - if test -d externalpackages/mpark.variant/include; then : - -else - if test -d .git && which git; then : - - make -f makefile.submodules mpark_submodule || \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "*** Could not download mpark.variant -See \`config.log' for more details" "$LINENO" 5; } - -else - - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "mpark.variant not found. Please install mpark.variant or use the official releases. -See \`config.log' for more details" "$LINENO" 5; } - -fi - -fi - - MPARK_VARIANT_INCLUDE_PATH="$PWD/externalpackages/mpark.variant/include" - MPARK_INCLUDE="-I$MPARK_VARIANT_INCLUDE_PATH" - OWN_MPARK=yes - -fi - -############################################################# -# Check for libuuid -############################################################# - -if test ".$with_system_uuid" = "no"; then : - - BOUT_HAS_UUID_SYSTEM_GENERATOR=no - -else - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid/uuid.h" >&5 -$as_echo_n "checking for uuid/uuid.h... " >&6; } - - save_CPPFLAGS=$CPPFLAGS - BACH_found=no - - if test ."$with_system_uuid" != .yes; then : - extra_prefix="$with_system_uuid" -else - extra_prefix="" -fi - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - BACH_found=yes - - - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - - if test $BACH_found != yes; then : - - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local - do - for path in $search_prefix $search_prefix/include - do - if test -d $path; then : - - CPPFLAGS="$save_CPPFLAGS -I$path" - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - #include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - BACH_found=yes - EXTRA_INCS="$EXTRA_INCS -I$path" - - - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -fi - done - if test .$BACH_found = .yes; then : - break; -fi - done - -fi - - if test $BACH_found = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - CPPFLAGS=$save_CPPFLAGS - -fi - if test .$BACH_found = .yes; then : - - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libuuid" >&5 -$as_echo_n "checking for libuuid... " >&6; } - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - BACL_found=no - - # Try with no extra libraries first - if test ."$with_system_uuid" = .yes; then : - extra_prefix="" -else - extra_prefix="$with_system_uuid" -fi - LIBS="$save_LIBS $EXTRA_LIBS" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char uuid_generate(); - -int -main () -{ -return uuid_generate(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS=$save_LIBS - - # Now try with explicitly linking library - if test $BACL_found != yes; then : - - LIBS="$save_LIBS $EXTRA_LIBS -luuid" - if test ."$with_system_uuid" = .yes; then : - extra_prefix="" -else - extra_prefix="$with_system_uuid" -fi - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char uuid_generate(); - -int -main () -{ -return uuid_generate(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -luuid" - - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - - if test $BACL_found != yes; then : - - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local ; do - for path in $search_prefix $search_prefix/lib $search_prefix/lib64 $search_prefix/x86_64-linux-gnu - do - if test -d $path; then : - - LIBS="$save_LIBS $EXTRA_LIBS -luuid" - LDFLAGS="$save_LDFLAGS -L$path" - - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - extern "C" - char uuid_generate(); - -int -main () -{ -return uuid_generate(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -L$path -luuid" - - - break -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - -fi - done - if test .$BACL_found = .yes; then : - break; -fi - done - -fi - - if test $BACL_found = yes; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -fi - - if test $BACL_found = yes; then : - BOUT_HAS_UUID_SYSTEM_GENERATOR=yes -else - BOUT_HAS_UUID_SYSTEM_GENERATOR=no -fi - - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS=$save_CPPFLAGS - ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - - -else - BOUT_HAS_UUID_SYSTEM_GENERATOR=no -fi - - if test "$with_system_uuid" = "yes"; then : - - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "*** System UUID generator not found, but explicitly requested -See \`config.log' for more details" "$LINENO" 5; } - -fi - -fi - -############################################################# -# Download + Build PVODE '98 -############################################################# - -as_dir=externalpackages; as_fn_mkdir_p -as_dir=lib; as_fn_mkdir_p -as_dir=include; as_fn_mkdir_p - -BOUT_HAS_PVODE="no" -if test "$with_pvode" != "no"; then : - - if test "$enable_pvode_openmp" != "no" ; then : - - if test "$enable_openmp" != "no" ; then : - - PVODE_FLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: PVODE being built with OpenMP support" >&5 -$as_echo "$as_me: PVODE being built with OpenMP support" >&6;} - -else - - as_fn_error $? "Cannot enable openmp in PVODE as configuring with OpenMP disabled" "$LINENO" 5 - -fi - -else - - PVODE_FLAGS="$CXXFLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: PVODE being built without OpenMP support" >&5 -$as_echo "$as_me: PVODE being built without OpenMP support" >&6;} - -fi - # Clean PVODE - CXX="$CXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE clean -C externalpackages/PVODE/precon/ >> config-build.log 2>&1 - CXX="$CXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE clean -C externalpackages/PVODE/source/ >> config-build.log 2>&1 - - { $as_echo "$as_me:${as_lineno-$LINENO}: Building PVODE" >&5 -$as_echo "$as_me: Building PVODE" >&6;} - echo "* Building PVODE" >> config-build.log - echo "*************************************************************" >> config-build.log - - CXX="$CXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE -C externalpackages/PVODE/precon/ >> config-build.log 2>&1 - CXX="$CXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE -C externalpackages/PVODE/source/ >> config-build.log 2>&1 - - if test -f externalpackages/PVODE/lib/libpvode.a && test -f externalpackages/PVODE/lib/libpvpre.a; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Successfully built PVODE" >&5 -$as_echo "$as_me: Successfully built PVODE" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: Installing PVODE into BOUT++ sourcetree" >&5 -$as_echo "$as_me: Installing PVODE into BOUT++ sourcetree" >&6;} - - echo "*************************************************************" >> config-build.log - echo "* Successfully built PVODE" >> config-build.log - echo "*************************************************************" >> config-build.log - echo "* Installing PVODE into BOUT++ sourcetree" >> config-build.log - echo "*************************************************************" >> config-build.log - -else - - as_fn_error $? "Could not build PVODE. See config-build.log for errors" "$LINENO" 5 - -fi - - # Set the correct libraries and copy them to bout - as_dir=include/pvode; as_fn_mkdir_p - cp -r externalpackages/PVODE/include/pvode include - cp externalpackages/PVODE/lib/*.a lib/ - EXTRA_LIBS="$EXTRA_LIBS -L\$(BOUT_LIB_PATH) -lpvode -lpvpre" - BOUT_HAS_PVODE="yes" - -fi - -############################################################# -# Localisation (i18n) with gettext -############################################################# - -BOUT_HAS_GETTEXT="no" -# Use macro to test if Natural Language Support (gettext) is available. -# If available sets: -# - USE_NLS to "yes" -# - LIBINTL to the linker options -# - Modifies CPPFLAGS if needed - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NLS is requested" >&5 -$as_echo_n "checking whether NLS is requested... " >&6; } - # Check whether --enable-nls was given. -if test "${enable_nls+set}" = set; then : - enableval=$enable_nls; USE_NLS=$enableval -else - USE_NLS=yes -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 -$as_echo "$USE_NLS" >&6; } - - - - - GETTEXT_MACRO_VERSION=0.19 - - - - -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which - # contains only /bin. Note that ksh looks also at the FPATH variable, - # so we have to set that as well for the test. - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - || PATH_SEPARATOR=';' - } -fi - -# Find out how to test for executable files. Don't use a zero-byte file, -# as systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - ac_executable_p="test -x" -else - ac_executable_p="test -f" -fi -rm -f conf$$.file - -# Extract the first word of "msgfmt", so it can be a program name with args. -set dummy msgfmt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MSGFMT+:} false; then : - $as_echo_n "(cached) " >&6 -else - case "$MSGFMT" in - [\\/]* | ?:[\\/]*) - ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. - ;; - *) - ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$ac_save_IFS" - test -z "$ac_dir" && ac_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then - echo "$as_me: trying $ac_dir/$ac_word..." >&5 - if $ac_dir/$ac_word --statistics /dev/null >&5 2>&1 && - (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - ac_cv_path_MSGFMT="$ac_dir/$ac_word$ac_exec_ext" - break 2 - fi - fi - done - done - IFS="$ac_save_IFS" - test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT=":" - ;; -esac -fi -MSGFMT="$ac_cv_path_MSGFMT" -if test "$MSGFMT" != ":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGFMT" >&5 -$as_echo "$MSGFMT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - # Extract the first word of "gmsgfmt", so it can be a program name with args. -set dummy gmsgfmt; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_GMSGFMT+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $GMSGFMT in - [\\/]* | ?:[\\/]*) - ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" - ;; -esac -fi -GMSGFMT=$ac_cv_path_GMSGFMT -if test -n "$GMSGFMT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GMSGFMT" >&5 -$as_echo "$GMSGFMT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in - '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;; - *) MSGFMT_015=$MSGFMT ;; - esac - - case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in - '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;; - *) GMSGFMT_015=$GMSGFMT ;; - esac - - - -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which - # contains only /bin. Note that ksh looks also at the FPATH variable, - # so we have to set that as well for the test. - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - || PATH_SEPARATOR=';' - } -fi - -# Find out how to test for executable files. Don't use a zero-byte file, -# as systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - ac_executable_p="test -x" -else - ac_executable_p="test -f" -fi -rm -f conf$$.file - -# Extract the first word of "xgettext", so it can be a program name with args. -set dummy xgettext; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_XGETTEXT+:} false; then : - $as_echo_n "(cached) " >&6 -else - case "$XGETTEXT" in - [\\/]* | ?:[\\/]*) - ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. - ;; - *) - ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$ac_save_IFS" - test -z "$ac_dir" && ac_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then - echo "$as_me: trying $ac_dir/$ac_word..." >&5 - if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&5 2>&1 && - (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi); then - ac_cv_path_XGETTEXT="$ac_dir/$ac_word$ac_exec_ext" - break 2 - fi - fi - done - done - IFS="$ac_save_IFS" - test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" - ;; -esac -fi -XGETTEXT="$ac_cv_path_XGETTEXT" -if test "$XGETTEXT" != ":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XGETTEXT" >&5 -$as_echo "$XGETTEXT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - rm -f messages.po - - case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in - '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;; - *) XGETTEXT_015=$XGETTEXT ;; - esac - - - -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which - # contains only /bin. Note that ksh looks also at the FPATH variable, - # so we have to set that as well for the test. - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - || PATH_SEPARATOR=';' - } -fi - -# Find out how to test for executable files. Don't use a zero-byte file, -# as systems may use methods other than mode bits to determine executability. -cat >conf$$.file <<_ASEOF -#! /bin/sh -exit 0 -_ASEOF -chmod +x conf$$.file -if test -x conf$$.file >/dev/null 2>&1; then - ac_executable_p="test -x" -else - ac_executable_p="test -f" -fi -rm -f conf$$.file - -# Extract the first word of "msgmerge", so it can be a program name with args. -set dummy msgmerge; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_MSGMERGE+:} false; then : - $as_echo_n "(cached) " >&6 -else - case "$MSGMERGE" in - [\\/]* | ?:[\\/]*) - ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path. - ;; - *) - ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$ac_save_IFS" - test -z "$ac_dir" && ac_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then - echo "$as_me: trying $ac_dir/$ac_word..." >&5 - if $ac_dir/$ac_word --update -q /dev/null /dev/null >&5 2>&1; then - ac_cv_path_MSGMERGE="$ac_dir/$ac_word$ac_exec_ext" - break 2 - fi - fi - done - done - IFS="$ac_save_IFS" - test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE=":" - ;; -esac -fi -MSGMERGE="$ac_cv_path_MSGMERGE" -if test "$MSGMERGE" != ":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MSGMERGE" >&5 -$as_echo "$MSGMERGE" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$localedir" || localedir='${datadir}/locale' - - - test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS= - - - ac_config_commands="$ac_config_commands po-directories" - - - - if test "X$prefix" = "XNONE"; then - acl_final_prefix="$ac_default_prefix" - else - acl_final_prefix="$prefix" - fi - if test "X$exec_prefix" = "XNONE"; then - acl_final_exec_prefix='${prefix}' - else - acl_final_exec_prefix="$exec_prefix" - fi - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" - prefix="$acl_save_prefix" - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=cpp -ac_cpp='$CXXCPP $CPPFLAGS' -ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_cxx_compiler_gnu - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - - - -# Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -# Prepare PATH_SEPARATOR. -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which - # contains only /bin. Note that ksh looks also at the FPATH variable, - # so we have to set that as well for the test. - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ - || PATH_SEPARATOR=';' - } -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`echo "$ac_prog"| sed 's%\\\\%/%g'` - while echo "$ac_prog" | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } -fi -if ${acl_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$acl_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - acl_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$acl_cv_path_LD" -v 2>&1 &5 -$as_echo "$LD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${acl_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 &5 -$as_echo "$acl_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$acl_cv_prog_gnu_ld - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 -$as_echo_n "checking for shared library run path origin... " >&6; } -if ${acl_cv_rpath+:} false; then : - $as_echo_n "(cached) " >&6 -else - - CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ - ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh - . ./conftest.sh - rm -f ./conftest.sh - acl_cv_rpath=done - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 -$as_echo "$acl_cv_rpath" >&6; } - wl="$acl_cv_wl" - acl_libext="$acl_cv_libext" - acl_shlibext="$acl_cv_shlibext" - acl_libname_spec="$acl_cv_libname_spec" - acl_library_names_spec="$acl_cv_library_names_spec" - acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" - acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" - acl_hardcode_direct="$acl_cv_hardcode_direct" - acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" - # Check whether --enable-rpath was given. -if test "${enable_rpath+set}" = set; then : - enableval=$enable_rpath; : -else - enable_rpath=yes -fi - - - - - acl_libdirstem=lib - acl_libdirstem2= - case "$host_os" in - solaris*) - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5 -$as_echo_n "checking for 64-bit host... " >&6; } -if ${gl_cv_solaris_64bit+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#ifdef _LP64 -sixtyfour bits -#endif - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "sixtyfour bits" >/dev/null 2>&1; then : - gl_cv_solaris_64bit=yes -else - gl_cv_solaris_64bit=no -fi -rm -f conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5 -$as_echo "$gl_cv_solaris_64bit" >&6; } - if test $gl_cv_solaris_64bit = yes; then - acl_libdirstem=lib/64 - case "$host_cpu" in - sparc*) acl_libdirstem2=lib/sparcv9 ;; - i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; - esac - fi - ;; - *) - searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` - if test -n "$searchpath"; then - acl_save_IFS="${IFS= }"; IFS=":" - for searchdir in $searchpath; do - if test -d "$searchdir"; then - case "$searchdir" in - */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; - */../ | */.. ) - # Better ignore directories of this form. They are misleading. - ;; - *) searchdir=`cd "$searchdir" && pwd` - case "$searchdir" in - */lib64 ) acl_libdirstem=lib64 ;; - esac ;; - esac - fi - done - IFS="$acl_save_IFS" - fi - ;; - esac - test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" - - - - - - - - - - - - - use_additional=yes - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - -# Check whether --with-libiconv-prefix was given. -if test "${with_libiconv_prefix+set}" = set; then : - withval=$with_libiconv_prefix; - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - else - additional_includedir="$withval/include" - additional_libdir="$withval/$acl_libdirstem" - if test "$acl_libdirstem2" != "$acl_libdirstem" \ - && ! test -d "$withval/$acl_libdirstem"; then - additional_libdir="$withval/$acl_libdirstem2" - fi - fi - fi - -fi - - LIBICONV= - LTLIBICONV= - INCICONV= - LIBICONV_PREFIX= - HAVE_LIBICONV= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='iconv ' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIBICONV="${LIBICONV}${LIBICONV:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$value" - else - : - fi - else - found_dir= - found_la= - found_so= - found_a= - eval libname=\"$acl_libname_spec\" # typically: libname=lib$name - if test -n "$acl_shlibext"; then - shrext=".$acl_shlibext" # typically: shrext=.so - else - shrext= - fi - if test $use_additional = yes; then - dir="$additional_libdir" - if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then - found_dir="$dir" - found_so="$dir/$libname$shrext" - else - if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then - ver=`(cd "$dir" && \ - for f in "$libname$shrext".*; do echo "$f"; done \ - | sed -e "s,^$libname$shrext\\\\.,," \ - | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ - | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then - found_dir="$dir" - found_so="$dir/$libname$shrext.$ver" - fi - else - eval library_names=\"$acl_library_names_spec\" - for f in $library_names; do - if test -f "$dir/$f"; then - found_dir="$dir" - found_so="$dir/$f" - break - fi - done - fi - fi - fi - if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then - found_dir="$dir" - found_a="$dir/$libname.$acl_libext" - fi - fi - if test "X$found_dir" != "X"; then - if test -f "$dir/$libname.la"; then - found_la="$dir/$libname.la" - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then - found_dir="$dir" - found_so="$dir/$libname$shrext" - else - if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then - ver=`(cd "$dir" && \ - for f in "$libname$shrext".*; do echo "$f"; done \ - | sed -e "s,^$libname$shrext\\\\.,," \ - | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ - | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then - found_dir="$dir" - found_so="$dir/$libname$shrext.$ver" - fi - else - eval library_names=\"$acl_library_names_spec\" - for f in $library_names; do - if test -f "$dir/$f"; then - found_dir="$dir" - found_so="$dir/$f" - break - fi - done - fi - fi - fi - if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then - found_dir="$dir" - found_a="$dir/$libname.$acl_libext" - fi - fi - if test "X$found_dir" != "X"; then - if test -f "$dir/$libname.la"; then - found_la="$dir/$libname.la" - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - if test "$enable_rpath" = no \ - || test "X$found_dir" = "X/usr/$acl_libdirstem" \ - || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - else - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - if test "$acl_hardcode_direct" = yes; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - else - if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - haveit= - for x in $LDFLAGS $LIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir" - fi - if test "$acl_hardcode_minus_L" != no; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_so" - else - LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }$found_a" - else - LIBICONV="${LIBICONV}${LIBICONV:+ }-L$found_dir -l$name" - fi - fi - additional_includedir= - case "$found_dir" in - */$acl_libdirstem | */$acl_libdirstem/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` - if test "$name" = 'iconv'; then - LIBICONV_PREFIX="$basedir" - fi - additional_includedir="$basedir/include" - ;; - */$acl_libdirstem2 | */$acl_libdirstem2/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` - if test "$name" = 'iconv'; then - LIBICONV_PREFIX="$basedir" - fi - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INCICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - INCICONV="${INCICONV}${INCICONV:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - if test -n "$found_la"; then - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ - && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ - || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LIBICONV="${LIBICONV}${LIBICONV:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIBICONV; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - LIBICONV="${LIBICONV}${LIBICONV:+ }$dep" - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }$dep" - ;; - esac - done - fi - else - LIBICONV="${LIBICONV}${LIBICONV:+ }-l$name" - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-l$name" - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$acl_hardcode_libdir_separator"; then - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" - done - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" - else - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBICONV="${LIBICONV}${LIBICONV:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - for found_dir in $ltrpathdirs; do - LTLIBICONV="${LTLIBICONV}${LTLIBICONV:+ }-R$found_dir" - done - fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFPreferencesCopyAppValue" >&5 -$as_echo_n "checking for CFPreferencesCopyAppValue... " >&6; } -if ${gt_cv_func_CFPreferencesCopyAppValue+:} false; then : - $as_echo_n "(cached) " >&6 -else - gt_save_LIBS="$LIBS" - LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -CFPreferencesCopyAppValue(NULL, NULL) - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - gt_cv_func_CFPreferencesCopyAppValue=yes -else - gt_cv_func_CFPreferencesCopyAppValue=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS="$gt_save_LIBS" -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFPreferencesCopyAppValue" >&5 -$as_echo "$gt_cv_func_CFPreferencesCopyAppValue" >&6; } - if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then - -$as_echo "#define HAVE_CFPREFERENCESCOPYAPPVALUE 1" >>confdefs.h - - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CFLocaleCopyCurrent" >&5 -$as_echo_n "checking for CFLocaleCopyCurrent... " >&6; } -if ${gt_cv_func_CFLocaleCopyCurrent+:} false; then : - $as_echo_n "(cached) " >&6 -else - gt_save_LIBS="$LIBS" - LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -CFLocaleCopyCurrent(); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - gt_cv_func_CFLocaleCopyCurrent=yes -else - gt_cv_func_CFLocaleCopyCurrent=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS="$gt_save_LIBS" -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_func_CFLocaleCopyCurrent" >&5 -$as_echo "$gt_cv_func_CFLocaleCopyCurrent" >&6; } - if test $gt_cv_func_CFLocaleCopyCurrent = yes; then - -$as_echo "#define HAVE_CFLOCALECOPYCURRENT 1" >>confdefs.h - - fi - INTL_MACOSX_LIBS= - if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test $gt_cv_func_CFLocaleCopyCurrent = yes; then - INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation" - fi - - - - - - - LIBINTL= - LTLIBINTL= - POSUB= - - case " $gt_needs " in - *" need-formatstring-macros "*) gt_api_version=3 ;; - *" need-ngettext "*) gt_api_version=2 ;; - *) gt_api_version=1 ;; - esac - gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc" - gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl" - - if test "$USE_NLS" = "yes"; then - gt_use_preinstalled_gnugettext=no - - - if test $gt_api_version -ge 3; then - gt_revision_test_code=' -#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1) -#endif -typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1]; -' - else - gt_revision_test_code= - fi - if test $gt_api_version -ge 2; then - gt_expression_test_code=' + * ngettext ("", "", 0)' - else - gt_expression_test_code= - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libc" >&5 -$as_echo_n "checking for GNU gettext in libc... " >&6; } -if eval \${$gt_func_gnugettext_libc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -extern int _nl_msg_cat_cntr; -extern int *_nl_domain_bindings; -#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) -#else -#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 -#endif -$gt_revision_test_code - -int -main () -{ - -bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - eval "$gt_func_gnugettext_libc=yes" -else - eval "$gt_func_gnugettext_libc=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$gt_func_gnugettext_libc - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - - if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" != "yes"; }; then - - - - - - am_save_CPPFLAGS="$CPPFLAGS" - - for element in $INCICONV; do - haveit= - for x in $CPPFLAGS; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" - fi - done - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv" >&5 -$as_echo_n "checking for iconv... " >&6; } -if ${am_cv_func_iconv+:} false; then : - $as_echo_n "(cached) " >&6 -else - - am_cv_func_iconv="no, consider installing GNU libiconv" - am_cv_lib_iconv=no - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include - -int -main () -{ -iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - am_cv_func_iconv=yes -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if test "$am_cv_func_iconv" != yes; then - am_save_LIBS="$LIBS" - LIBS="$LIBS $LIBICONV" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include - -int -main () -{ -iconv_t cd = iconv_open("",""); - iconv(cd,NULL,NULL,NULL,NULL); - iconv_close(cd); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - am_cv_lib_iconv=yes - am_cv_func_iconv=yes -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LIBS="$am_save_LIBS" - fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv" >&5 -$as_echo "$am_cv_func_iconv" >&6; } - if test "$am_cv_func_iconv" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working iconv" >&5 -$as_echo_n "checking for working iconv... " >&6; } -if ${am_cv_func_iconv_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - - am_save_LIBS="$LIBS" - if test $am_cv_lib_iconv = yes; then - LIBS="$LIBS $LIBICONV" - fi - am_cv_func_iconv_works=no - for ac_iconv_const in '' 'const'; do - if test "$cross_compiling" = yes; then : - case "$host_os" in - aix* | hpux*) am_cv_func_iconv_works="guessing no" ;; - *) am_cv_func_iconv_works="guessing yes" ;; - esac -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#include - -#ifndef ICONV_CONST -# define ICONV_CONST $ac_iconv_const -#endif - -int -main () -{ -int result = 0; - /* Test against AIX 5.1 bug: Failures are not distinguishable from successful - returns. */ - { - iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8"); - if (cd_utf8_to_88591 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\342\202\254"; /* EURO SIGN */ - char buf[10]; - ICONV_CONST char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_utf8_to_88591, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res == 0) - result |= 1; - iconv_close (cd_utf8_to_88591); - } - } - /* Test against Solaris 10 bug: Failures are not distinguishable from - successful returns. */ - { - iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646"); - if (cd_ascii_to_88591 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\263"; - char buf[10]; - ICONV_CONST char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_ascii_to_88591, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res == 0) - result |= 2; - iconv_close (cd_ascii_to_88591); - } - } - /* Test against AIX 6.1..7.1 bug: Buffer overrun. */ - { - iconv_t cd_88591_to_utf8 = iconv_open ("UTF-8", "ISO-8859-1"); - if (cd_88591_to_utf8 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\304"; - static char buf[2] = { (char)0xDE, (char)0xAD }; - ICONV_CONST char *inptr = input; - size_t inbytesleft = 1; - char *outptr = buf; - size_t outbytesleft = 1; - size_t res = iconv (cd_88591_to_utf8, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if (res != (size_t)(-1) || outptr - buf > 1 || buf[1] != (char)0xAD) - result |= 4; - iconv_close (cd_88591_to_utf8); - } - } -#if 0 /* This bug could be worked around by the caller. */ - /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */ - { - iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591"); - if (cd_88591_to_utf8 != (iconv_t)(-1)) - { - static ICONV_CONST char input[] = "\304rger mit b\366sen B\374bchen ohne Augenma\337"; - char buf[50]; - ICONV_CONST char *inptr = input; - size_t inbytesleft = strlen (input); - char *outptr = buf; - size_t outbytesleft = sizeof (buf); - size_t res = iconv (cd_88591_to_utf8, - &inptr, &inbytesleft, - &outptr, &outbytesleft); - if ((int)res > 0) - result |= 8; - iconv_close (cd_88591_to_utf8); - } - } -#endif - /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is - provided. */ - if (/* Try standardized names. */ - iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1) - /* Try IRIX, OSF/1 names. */ - && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1) - /* Try AIX names. */ - && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1) - /* Try HP-UX names. */ - && iconv_open ("utf8", "eucJP") == (iconv_t)(-1)) - result |= 16; - return result; - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_run "$LINENO"; then : - am_cv_func_iconv_works=yes -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - - test "$am_cv_func_iconv_works" = no || break - done - LIBS="$am_save_LIBS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_func_iconv_works" >&5 -$as_echo "$am_cv_func_iconv_works" >&6; } - case "$am_cv_func_iconv_works" in - *no) am_func_iconv=no am_cv_lib_iconv=no ;; - *) am_func_iconv=yes ;; - esac - else - am_func_iconv=no am_cv_lib_iconv=no - fi - if test "$am_func_iconv" = yes; then - -$as_echo "#define HAVE_ICONV 1" >>confdefs.h - - fi - if test "$am_cv_lib_iconv" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libiconv" >&5 -$as_echo_n "checking how to link with libiconv... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBICONV" >&5 -$as_echo "$LIBICONV" >&6; } - else - CPPFLAGS="$am_save_CPPFLAGS" - LIBICONV= - LTLIBICONV= - fi - - - - - - - - - - - - use_additional=yes - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - -# Check whether --with-libintl-prefix was given. -if test "${with_libintl_prefix+set}" = set; then : - withval=$with_libintl_prefix; - if test "X$withval" = "Xno"; then - use_additional=no - else - if test "X$withval" = "X"; then - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - - eval additional_includedir=\"$includedir\" - eval additional_libdir=\"$libdir\" - - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - else - additional_includedir="$withval/include" - additional_libdir="$withval/$acl_libdirstem" - if test "$acl_libdirstem2" != "$acl_libdirstem" \ - && ! test -d "$withval/$acl_libdirstem"; then - additional_libdir="$withval/$acl_libdirstem2" - fi - fi - fi - -fi - - LIBINTL= - LTLIBINTL= - INCINTL= - LIBINTL_PREFIX= - HAVE_LIBINTL= - rpathdirs= - ltrpathdirs= - names_already_handled= - names_next_round='intl ' - while test -n "$names_next_round"; do - names_this_round="$names_next_round" - names_next_round= - for name in $names_this_round; do - already_handled= - for n in $names_already_handled; do - if test "$n" = "$name"; then - already_handled=yes - break - fi - done - if test -z "$already_handled"; then - names_already_handled="$names_already_handled $name" - uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` - eval value=\"\$HAVE_LIB$uppername\" - if test -n "$value"; then - if test "$value" = yes; then - eval value=\"\$LIB$uppername\" - test -z "$value" || LIBINTL="${LIBINTL}${LIBINTL:+ }$value" - eval value=\"\$LTLIB$uppername\" - test -z "$value" || LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$value" - else - : - fi - else - found_dir= - found_la= - found_so= - found_a= - eval libname=\"$acl_libname_spec\" # typically: libname=lib$name - if test -n "$acl_shlibext"; then - shrext=".$acl_shlibext" # typically: shrext=.so - else - shrext= - fi - if test $use_additional = yes; then - dir="$additional_libdir" - if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then - found_dir="$dir" - found_so="$dir/$libname$shrext" - else - if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then - ver=`(cd "$dir" && \ - for f in "$libname$shrext".*; do echo "$f"; done \ - | sed -e "s,^$libname$shrext\\\\.,," \ - | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ - | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then - found_dir="$dir" - found_so="$dir/$libname$shrext.$ver" - fi - else - eval library_names=\"$acl_library_names_spec\" - for f in $library_names; do - if test -f "$dir/$f"; then - found_dir="$dir" - found_so="$dir/$f" - break - fi - done - fi - fi - fi - if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then - found_dir="$dir" - found_a="$dir/$libname.$acl_libext" - fi - fi - if test "X$found_dir" != "X"; then - if test -f "$dir/$libname.la"; then - found_la="$dir/$libname.la" - fi - fi - fi - if test "X$found_dir" = "X"; then - for x in $LDFLAGS $LTLIBINTL; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - case "$x" in - -L*) - dir=`echo "X$x" | sed -e 's/^X-L//'` - if test -n "$acl_shlibext"; then - if test -f "$dir/$libname$shrext"; then - found_dir="$dir" - found_so="$dir/$libname$shrext" - else - if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then - ver=`(cd "$dir" && \ - for f in "$libname$shrext".*; do echo "$f"; done \ - | sed -e "s,^$libname$shrext\\\\.,," \ - | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ - | sed 1q ) 2>/dev/null` - if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then - found_dir="$dir" - found_so="$dir/$libname$shrext.$ver" - fi - else - eval library_names=\"$acl_library_names_spec\" - for f in $library_names; do - if test -f "$dir/$f"; then - found_dir="$dir" - found_so="$dir/$f" - break - fi - done - fi - fi - fi - if test "X$found_dir" = "X"; then - if test -f "$dir/$libname.$acl_libext"; then - found_dir="$dir" - found_a="$dir/$libname.$acl_libext" - fi - fi - if test "X$found_dir" != "X"; then - if test -f "$dir/$libname.la"; then - found_la="$dir/$libname.la" - fi - fi - ;; - esac - if test "X$found_dir" != "X"; then - break - fi - done - fi - if test "X$found_dir" != "X"; then - LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$found_dir -l$name" - if test "X$found_so" != "X"; then - if test "$enable_rpath" = no \ - || test "X$found_dir" = "X/usr/$acl_libdirstem" \ - || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then - LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" - else - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $found_dir" - fi - if test "$acl_hardcode_direct" = yes; then - LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" - else - if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then - LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $found_dir" - fi - else - haveit= - for x in $LDFLAGS $LIBINTL; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$found_dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir" - fi - if test "$acl_hardcode_minus_L" != no; then - LIBINTL="${LIBINTL}${LIBINTL:+ }$found_so" - else - LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" - fi - fi - fi - fi - else - if test "X$found_a" != "X"; then - LIBINTL="${LIBINTL}${LIBINTL:+ }$found_a" - else - LIBINTL="${LIBINTL}${LIBINTL:+ }-L$found_dir -l$name" - fi - fi - additional_includedir= - case "$found_dir" in - */$acl_libdirstem | */$acl_libdirstem/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` - if test "$name" = 'intl'; then - LIBINTL_PREFIX="$basedir" - fi - additional_includedir="$basedir/include" - ;; - */$acl_libdirstem2 | */$acl_libdirstem2/) - basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` - if test "$name" = 'intl'; then - LIBINTL_PREFIX="$basedir" - fi - additional_includedir="$basedir/include" - ;; - esac - if test "X$additional_includedir" != "X"; then - if test "X$additional_includedir" != "X/usr/include"; then - haveit= - if test "X$additional_includedir" = "X/usr/local/include"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - for x in $CPPFLAGS $INCINTL; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-I$additional_includedir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_includedir"; then - INCINTL="${INCINTL}${INCINTL:+ }-I$additional_includedir" - fi - fi - fi - fi - fi - if test -n "$found_la"; then - save_libdir="$libdir" - case "$found_la" in - */* | *\\*) . "$found_la" ;; - *) . "./$found_la" ;; - esac - libdir="$save_libdir" - for dep in $dependency_libs; do - case "$dep" in - -L*) - additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` - if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ - && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then - haveit= - if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ - || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then - if test -n "$GCC"; then - case $host_os in - linux* | gnu* | k*bsd*-gnu) haveit=yes;; - esac - fi - fi - if test -z "$haveit"; then - haveit= - for x in $LDFLAGS $LIBINTL; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LIBINTL="${LIBINTL}${LIBINTL:+ }-L$additional_libdir" - fi - fi - haveit= - for x in $LDFLAGS $LTLIBINTL; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X-L$additional_libdir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - if test -d "$additional_libdir"; then - LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-L$additional_libdir" - fi - fi - fi - fi - ;; - -R*) - dir=`echo "X$dep" | sed -e 's/^X-R//'` - if test "$enable_rpath" != no; then - haveit= - for x in $rpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - rpathdirs="$rpathdirs $dir" - fi - haveit= - for x in $ltrpathdirs; do - if test "X$x" = "X$dir"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - ltrpathdirs="$ltrpathdirs $dir" - fi - fi - ;; - -l*) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` - ;; - *.la) - names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` - ;; - *) - LIBINTL="${LIBINTL}${LIBINTL:+ }$dep" - LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }$dep" - ;; - esac - done - fi - else - LIBINTL="${LIBINTL}${LIBINTL:+ }-l$name" - LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-l$name" - fi - fi - fi - done - done - if test "X$rpathdirs" != "X"; then - if test -n "$acl_hardcode_libdir_separator"; then - alldirs= - for found_dir in $rpathdirs; do - alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" - done - acl_save_libdir="$libdir" - libdir="$alldirs" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" - else - for found_dir in $rpathdirs; do - acl_save_libdir="$libdir" - libdir="$found_dir" - eval flag=\"$acl_hardcode_libdir_flag_spec\" - libdir="$acl_save_libdir" - LIBINTL="${LIBINTL}${LIBINTL:+ }$flag" - done - fi - fi - if test "X$ltrpathdirs" != "X"; then - for found_dir in $ltrpathdirs; do - LTLIBINTL="${LTLIBINTL}${LTLIBINTL:+ }-R$found_dir" - done - fi - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU gettext in libintl" >&5 -$as_echo_n "checking for GNU gettext in libintl... " >&6; } -if eval \${$gt_func_gnugettext_libintl+:} false; then : - $as_echo_n "(cached) " >&6 -else - gt_save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $INCINTL" - gt_save_LIBS="$LIBS" - LIBS="$LIBS $LIBINTL" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias (const char *); -#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) -#else -#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 -#endif -$gt_revision_test_code - -int -main () -{ - -bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - eval "$gt_func_gnugettext_libintl=yes" -else - eval "$gt_func_gnugettext_libintl=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" != yes; } && test -n "$LIBICONV"; then - LIBS="$LIBS $LIBICONV" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#include -#ifndef __GNU_GETTEXT_SUPPORTED_REVISION -extern int _nl_msg_cat_cntr; -extern -#ifdef __cplusplus -"C" -#endif -const char *_nl_expand_alias (const char *); -#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) -#else -#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 -#endif -$gt_revision_test_code - -int -main () -{ - -bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION - - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_link "$LINENO"; then : - LIBINTL="$LIBINTL $LIBICONV" - LTLIBINTL="$LTLIBINTL $LTLIBICONV" - eval "$gt_func_gnugettext_libintl=yes" - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - fi - CPPFLAGS="$gt_save_CPPFLAGS" - LIBS="$gt_save_LIBS" -fi -eval ac_res=\$$gt_func_gnugettext_libintl - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - fi - - if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val" = "yes"; } \ - || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; } \ - && test "$PACKAGE" != gettext-runtime \ - && test "$PACKAGE" != gettext-tools; }; then - gt_use_preinstalled_gnugettext=yes - else - LIBINTL= - LTLIBINTL= - INCINTL= - fi - - - - if test -n "$INTL_MACOSX_LIBS"; then - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - LIBINTL="$LIBINTL $INTL_MACOSX_LIBS" - LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS" - fi - fi - - if test "$gt_use_preinstalled_gnugettext" = "yes" \ - || test "$nls_cv_use_gnu_gettext" = "yes"; then - -$as_echo "#define ENABLE_NLS 1" >>confdefs.h - - else - USE_NLS=no - fi - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use NLS" >&5 -$as_echo_n "checking whether to use NLS... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_NLS" >&5 -$as_echo "$USE_NLS" >&6; } - if test "$USE_NLS" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking where the gettext function comes from" >&5 -$as_echo_n "checking where the gettext function comes from... " >&6; } - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then - gt_source="external libintl" - else - gt_source="libc" - fi - else - gt_source="included intl directory" - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_source" >&5 -$as_echo "$gt_source" >&6; } - fi - - if test "$USE_NLS" = "yes"; then - - if test "$gt_use_preinstalled_gnugettext" = "yes"; then - if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test "$gt_val" = "yes"; }; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to link with libintl" >&5 -$as_echo_n "checking how to link with libintl... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBINTL" >&5 -$as_echo "$LIBINTL" >&6; } - - for element in $INCINTL; do - haveit= - for x in $CPPFLAGS; do - - acl_save_prefix="$prefix" - prefix="$acl_final_prefix" - acl_save_exec_prefix="$exec_prefix" - exec_prefix="$acl_final_exec_prefix" - eval x=\"$x\" - exec_prefix="$acl_save_exec_prefix" - prefix="$acl_save_prefix" - - if test "X$x" = "X$element"; then - haveit=yes - break - fi - done - if test -z "$haveit"; then - CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }$element" - fi - done - - fi - - -$as_echo "#define HAVE_GETTEXT 1" >>confdefs.h - - -$as_echo "#define HAVE_DCGETTEXT 1" >>confdefs.h - - fi - - POSUB=po - fi - - - - INTLLIBS="$LIBINTL" - - - - - - -if test "$USE_NLS" = "yes"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling language support with gettext" >&5 -$as_echo "$as_me: Enabling language support with gettext" >&6;} - # Turn the .po files into .mo files - $MAKE -C locale | tee -a config-build.log 2>&1 - - # Note: BOUT_LOCALE_PATH is defined in make.config, and may be changed by `make install`. - CXXFLAGS="$CXXFLAGS -DBOUT_LOCALE_PATH=\$(BOUT_LOCALE_PATH)" - - EXTRA_LIBS="$EXTRA_LIBS $LIBINTL" - - # Set variable substituted into bout-config - BOUT_HAS_GETTEXT="yes" - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Language support with gettext not available" >&5 -$as_echo "$as_me: Language support with gettext not available" >&6;} - -fi - -############################################################# -# Sort out fmt -############################################################# - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for .git" >&5 -$as_echo_n "checking for .git... " >&6; } -if ${ac_cv_file__git+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r ".git"; then - ac_cv_file__git=yes -else - ac_cv_file__git=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_file__git" >&5 -$as_echo "$ac_cv_file__git" >&6; } -if test "x$ac_cv_file__git" = xyes; then : - - if test "x$BOUT_DONT_UPDATE_GIT_SUBMODULE" == "x"; then : - - git submodule update --init externalpackages/fmt - -fi - -fi - - -ac_config_links="$ac_config_links src/fmt/format.cxx:externalpackages/fmt/src/format.cc" - - -############################################################# -# Check environment -############################################################# - -if test "$CXXINCLUDE" != ""; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: ================================================" >&5 -$as_echo "$as_me: ================================================" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: CXXINCLUDE environment variable set to:" >&5 -$as_echo "$as_me: WARNING: CXXINCLUDE environment variable set to:" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: $CXXINCLUDE" >&5 -$as_echo "$as_me: $CXXINCLUDE" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: => This will be added to compile commands" >&5 -$as_echo "$as_me: => This will be added to compile commands" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: If this is not intended, then run" >&5 -$as_echo "$as_me: If this is not intended, then run" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: export CXXINCLUDE=''" >&5 -$as_echo "$as_me: export CXXINCLUDE=''" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: before making BOUT++" >&5 -$as_echo "$as_me: before making BOUT++" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: ================================================" >&5 -$as_echo "$as_me: ================================================" >&6;} - -fi - -############################################################# -# Gather configuration info for bout-config -############################################################# - -EXTRA_INCS="${EXTRA_INCS} ${CPPFLAGS}" - -PREFIX=$PWD -IDLCONFIGPATH=$PWD/tools/idllib -PYTHONCONFIGPATH=$PWD/tools/pylib - -BOUT_HAS_IDA="yes" -if test "$IDALIBS" = "" -then - BOUT_HAS_IDA="no" -fi - -BOUT_HAS_CVODE="yes" -if test "$CVODELIBS" = "" -then - BOUT_HAS_CVODE="no" -fi - -BOUT_HAS_ARKODE="yes" -if test "$ARKODELIBS" = "" -then - BOUT_HAS_ARKODE="no" -fi - -BOUT_HAS_PNETCDF="yes" -if test "$PNCPATH" = "" -then - BOUT_HAS_PNETCDF="no" -fi - -# Only make.config is altered by configure -ac_config_files="$ac_config_files make.config" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -# -# If the first sed substitution is executed (which looks for macros that -# take arguments), then branch to the quote section. Otherwise, -# look for a macro that doesn't take arguments. -ac_script=' -:mline -/\\$/{ - N - s,\\\n,, - b mline -} -t clear -:clear -s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g -t quote -s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g -t quote -b any -:quote -s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g -s/\[/\\&/g -s/\]/\\&/g -s/\$/$$/g -H -:any -${ - g - s/^\n// - s/\n/ /g - p -} -' -DEFS=`sed -n "$ac_script" confdefs.h` - - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -if test -z "${CODE_COVERAGE_ENABLED_TRUE}" && test -z "${CODE_COVERAGE_ENABLED_FALSE}"; then - as_fn_error $? "conditional \"CODE_COVERAGE_ENABLED\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by BOUT++ $as_me 5.1.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_links="$ac_config_links" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - -Configuration files: -$config_files - -Configuration links: -$config_links - -Configuration commands: -$config_commands - -Report bugs to ." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -BOUT++ config.status 5.1.0 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h | --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -# Capture the value of obsolete ALL_LINGUAS because we need it to compute - # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it - # from automake < 1.5. - eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' - # Capture the value of LINGUAS because we need it to compute CATALOGS. - LINGUAS="${LINGUAS-%UNSET%}" - - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; - "src/fmt/format.cxx") CONFIG_LINKS="$CONFIG_LINKS src/fmt/format.cxx:externalpackages/fmt/src/format.cc" ;; - "make.config") CONFIG_FILES="$CONFIG_FILES make.config" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - - -eval set X " :F $CONFIG_FILES :L $CONFIG_LINKS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - - :L) - # - # CONFIG_LINK - # - - if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then - : - else - # Prefer the file from the source tree if names are identical. - if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then - ac_source=$srcdir/$ac_source - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5 -$as_echo "$as_me: linking $ac_source to $ac_file" >&6;} - - if test ! -r "$ac_source"; then - as_fn_error $? "$ac_source: file not found" "$LINENO" 5 - fi - rm -f "$ac_file" - - # Try a relative symlink, then a hard link, then a copy. - case $ac_source in - [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;; - *) ac_rel_source=$ac_top_build_prefix$ac_source ;; - esac - ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || - ln "$ac_source" "$ac_file" 2>/dev/null || - cp -p "$ac_source" "$ac_file" || - as_fn_error $? "cannot link or copy $ac_source to $ac_file" "$LINENO" 5 - fi - ;; - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "po-directories":C) - for ac_file in $CONFIG_FILES; do - # Support "outfile[:infile[:infile...]]" - case "$ac_file" in - *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - esac - # PO directories have a Makefile.in generated from Makefile.in.in. - case "$ac_file" in */Makefile.in) - # Adjust a relative srcdir. - ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` - ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` - ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` - # In autoconf-2.13 it is called $ac_given_srcdir. - # In autoconf-2.50 it is called $srcdir. - test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" - case "$ac_given_srcdir" in - .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; - /*) top_srcdir="$ac_given_srcdir" ;; - *) top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - # Treat a directory as a PO directory if and only if it has a - # POTFILES.in file. This allows packages to have multiple PO - # directories under different names or in different locations. - if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then - rm -f "$ac_dir/POTFILES" - test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" - gt_tab=`printf '\t'` - cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" - POMAKEFILEDEPS="POTFILES.in" - # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend - # on $ac_dir but don't depend on user-specified configuration - # parameters. - if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then - # The LINGUAS file contains the set of available languages. - if test -n "$OBSOLETE_ALL_LINGUAS"; then - test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" - fi - ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` - # Hide the ALL_LINGUAS assignment from automake < 1.5. - eval 'ALL_LINGUAS''=$ALL_LINGUAS_' - POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" - else - # The set of available languages was given in configure.in. - # Hide the ALL_LINGUAS assignment from automake < 1.5. - eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' - fi - # Compute POFILES - # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) - # Compute UPDATEPOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) - # Compute DUMMYPOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) - # Compute GMOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) - case "$ac_given_srcdir" in - .) srcdirpre= ;; - *) srcdirpre='$(srcdir)/' ;; - esac - POFILES= - UPDATEPOFILES= - DUMMYPOFILES= - GMOFILES= - for lang in $ALL_LINGUAS; do - POFILES="$POFILES $srcdirpre$lang.po" - UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" - DUMMYPOFILES="$DUMMYPOFILES $lang.nop" - GMOFILES="$GMOFILES $srcdirpre$lang.gmo" - done - # CATALOGS depends on both $ac_dir and the user's LINGUAS - # environment variable. - INST_LINGUAS= - if test -n "$ALL_LINGUAS"; then - for presentlang in $ALL_LINGUAS; do - useit=no - if test "%UNSET%" != "$LINGUAS"; then - desiredlanguages="$LINGUAS" - else - desiredlanguages="$ALL_LINGUAS" - fi - for desiredlang in $desiredlanguages; do - # Use the presentlang catalog if desiredlang is - # a. equal to presentlang, or - # b. a variant of presentlang (because in this case, - # presentlang can be used as a fallback for messages - # which are not translated in the desiredlang catalog). - case "$desiredlang" in - "$presentlang"*) useit=yes;; - esac - done - if test $useit = yes; then - INST_LINGUAS="$INST_LINGUAS $presentlang" - fi - done - fi - CATALOGS= - if test -n "$INST_LINGUAS"; then - for lang in $INST_LINGUAS; do - CATALOGS="$CATALOGS $lang.gmo" - done - fi - test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" - sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" - for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do - if test -f "$f"; then - case "$f" in - *.orig | *.bak | *~) ;; - *) cat "$f" >> "$ac_dir/Makefile" ;; - esac - fi - done - fi - ;; - esac - done ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - - -############################################################# -# Use a dummy Makefile to get the cflags and ldflags -# -# This is to capture flags from external libraries such -# as PETSc -############################################################# - -CONFIG_CFLAGS=`$MAKE cflags -f output.make` -CONFIG_LDFLAGS=`$MAKE ldflags -f output.make` - -############################################################# -# Defines which are supported by CMake build but not autoconf - -BOUT_HAS_CUDA="no" -BOUT_HAS_RAJA="no" -BOUT_HAS_UMPIRE="no" -BOUT_HAS_CALIPER="no" - - -if test "x$BOUT_HAS_CUDA" = "xyes"; then : - -$as_echo "#define BOUT_HAS_CUDA 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_CUDA 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_RAJA" = "xyes"; then : - -$as_echo "#define BOUT_HAS_RAJA 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_RAJA 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_UMPIRE" = "xyes"; then : - -$as_echo "#define BOUT_HAS_UMPIRE 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_UMPIRE 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_CALIPER" = "xyes"; then : - -$as_echo "#define BOUT_HAS_CALIPER 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_CALIPER 0" >>confdefs.h - -fi - - - -############################################################# -# Write configuration to bout-config -############################################################# - - - - -# Set path to lib and include here. -# If make install is run then that replaces these paths -BOUT_LIB_PATH=$PWD/lib -BOUT_INCLUDE_PATH=$PWD/include -FMT_INCLUDE_PATH=$PWD/externalpackages/fmt/include - - - - - - - - - - - - - - - - - - - - - - - -cat >>confdefs.h <<_ACEOF -#define BOUT_CHECK_LEVEL $BOUT_CHECK_LEVEL -_ACEOF - - - - -cat >>confdefs.h <<_ACEOF -#define BOUT_OPENMP_SCHEDULE $BOUT_OPENMP_SCHEDULE -_ACEOF - - - -if test "x$BOUT_HAS_ARKODE" = "xyes"; then : - -$as_echo "#define BOUT_HAS_ARKODE 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_ARKODE 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_CVODE" = "xyes"; then : - -$as_echo "#define BOUT_HAS_CVODE 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_CVODE 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_FFTW" = "xyes"; then : - -$as_echo "#define BOUT_HAS_FFTW 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_FFTW 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_GETTEXT" = "xyes"; then : - -$as_echo "#define BOUT_HAS_GETTEXT 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_GETTEXT 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_IDA" = "xyes"; then : - -$as_echo "#define BOUT_HAS_IDA 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_IDA 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_LAPACK" = "xyes"; then : - -$as_echo "#define BOUT_HAS_LAPACK 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_LAPACK 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_NETCDF" = "xyes"; then : - -$as_echo "#define BOUT_HAS_NETCDF 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_NETCDF 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_LEGACY_NETCDF" = "xyes"; then : - -$as_echo "#define BOUT_HAS_LEGACY_NETCDF 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_LEGACY_NETCDF 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_PETSC" = "xyes"; then : - -$as_echo "#define BOUT_HAS_PETSC 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_PETSC 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_HYPRE" = "xyes"; then : - -$as_echo "#define BOUT_HAS_HYPRE 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_HYPRE 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_PNETCDF" = "xyes"; then : - -$as_echo "#define BOUT_HAS_PNETCDF 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_PNETCDF 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_PRETTY_FUNCTION" = "xyes"; then : - -$as_echo "#define BOUT_HAS_PRETTY_FUNCTION 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_PRETTY_FUNCTION 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_PVODE" = "xyes"; then : - -$as_echo "#define BOUT_HAS_PVODE 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_PVODE 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_SCOREP" = "xyes"; then : - -$as_echo "#define BOUT_HAS_SCOREP 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_SCOREP 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_SLEPC" = "xyes"; then : - -$as_echo "#define BOUT_HAS_SLEPC 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_SLEPC 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_SUNDIALS" = "xyes"; then : - -$as_echo "#define BOUT_HAS_SUNDIALS 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_SUNDIALS 0" >>confdefs.h - -fi - - - -if test "x$BOUT_HAS_UUID_SYSTEM_GENERATOR" = "xyes"; then : - -$as_echo "#define BOUT_HAS_UUID_SYSTEM_GENERATOR 1" >>confdefs.h - -else - -$as_echo "#define BOUT_HAS_UUID_SYSTEM_GENERATOR 0" >>confdefs.h - -fi - - - -if test "x$BOUT_USE_BACKTRACE" = "xyes"; then : - -$as_echo "#define BOUT_USE_BACKTRACE 1" >>confdefs.h - -else - -$as_echo "#define BOUT_USE_BACKTRACE 0" >>confdefs.h - -fi - - - -if test "x$BOUT_USE_COLOR" = "xyes"; then : - -$as_echo "#define BOUT_USE_COLOR 1" >>confdefs.h - -else - -$as_echo "#define BOUT_USE_COLOR 0" >>confdefs.h - -fi - - - -if test "x$BOUT_USE_OUTPUT_DEBUG" = "xyes"; then : - -$as_echo "#define BOUT_USE_OUTPUT_DEBUG 1" >>confdefs.h - -else - -$as_echo "#define BOUT_USE_OUTPUT_DEBUG 0" >>confdefs.h - -fi - - - -if test "x$BOUT_USE_OPENMP" = "xyes"; then : - -$as_echo "#define BOUT_USE_OPENMP 1" >>confdefs.h - -else - -$as_echo "#define BOUT_USE_OPENMP 0" >>confdefs.h - -fi - - - -if test "x$BOUT_USE_SIGFPE" = "xyes"; then : - -$as_echo "#define BOUT_USE_SIGFPE 1" >>confdefs.h - -else - -$as_echo "#define BOUT_USE_SIGFPE 0" >>confdefs.h - -fi - - - -if test "x$BOUT_USE_SIGNAL" = "xyes"; then : - -$as_echo "#define BOUT_USE_SIGNAL 1" >>confdefs.h - -else - -$as_echo "#define BOUT_USE_SIGNAL 0" >>confdefs.h - -fi - - - -if test "x$BOUT_USE_TRACK" = "xyes"; then : - -$as_echo "#define BOUT_USE_TRACK 1" >>confdefs.h - -else - -$as_echo "#define BOUT_USE_TRACK 0" >>confdefs.h - -fi - - - -if test "x$BOUT_USE_MSGSTACK" = "xyes"; then : - -$as_echo "#define BOUT_USE_MSGSTACK 1" >>confdefs.h - -else - -$as_echo "#define BOUT_USE_MSGSTACK 0" >>confdefs.h - -fi - - - -cat >>confdefs.h <<_ACEOF -#define BOUT_METRIC_TYPE $BOUT_METRIC_TYPE -_ACEOF - -BOUT_METRIC_3D=$(test $BOUT_METRIC_TYPE != 3D ; echo $?) - -cat >>confdefs.h <<_ACEOF -#define BOUT_USE_METRIC_3D $BOUT_METRIC_3D -_ACEOF - - - - - - - - - - - - -ac_config_headers="$ac_config_headers include/bout/build_defines.hxx:autoconf_build_defines.hxx.in" - -ac_config_files="$ac_config_files include/bout/version.hxx" - -ac_config_files="$ac_config_files include/bout/revision.hxx" - -ac_config_files="$ac_config_files bin/bout-config" - -ac_config_files="$ac_config_files src/makefile" - -ac_config_files="$ac_config_files tools/pylib/boutconfig/__init__.py" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - -if test -z "${CODE_COVERAGE_ENABLED_TRUE}" && test -z "${CODE_COVERAGE_ENABLED_FALSE}"; then - as_fn_error $? "conditional \"CODE_COVERAGE_ENABLED\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by BOUT++ $as_me 5.1.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_links="$ac_config_links" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration links: -$config_links - -Configuration commands: -$config_commands - -Report bugs to ." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -BOUT++ config.status 5.1.0 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -# Capture the value of obsolete ALL_LINGUAS because we need it to compute - # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it - # from automake < 1.5. - eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"' - # Capture the value of LINGUAS because we need it to compute CATALOGS. - LINGUAS="${LINGUAS-%UNSET%}" - - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; - "src/fmt/format.cxx") CONFIG_LINKS="$CONFIG_LINKS src/fmt/format.cxx:externalpackages/fmt/src/format.cc" ;; - "make.config") CONFIG_FILES="$CONFIG_FILES make.config" ;; - "include/bout/build_defines.hxx") CONFIG_HEADERS="$CONFIG_HEADERS include/bout/build_defines.hxx:autoconf_build_defines.hxx.in" ;; - "include/bout/version.hxx") CONFIG_FILES="$CONFIG_FILES include/bout/version.hxx" ;; - "include/bout/revision.hxx") CONFIG_FILES="$CONFIG_FILES include/bout/revision.hxx" ;; - "bin/bout-config") CONFIG_FILES="$CONFIG_FILES bin/bout-config" ;; - "src/makefile") CONFIG_FILES="$CONFIG_FILES src/makefile" ;; - "tools/pylib/boutconfig/__init__.py") CONFIG_FILES="$CONFIG_FILES tools/pylib/boutconfig/__init__.py" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :L $CONFIG_LINKS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi - ;; - :L) - # - # CONFIG_LINK - # - - if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then - : - else - # Prefer the file from the source tree if names are identical. - if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then - ac_source=$srcdir/$ac_source - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5 -$as_echo "$as_me: linking $ac_source to $ac_file" >&6;} - - if test ! -r "$ac_source"; then - as_fn_error $? "$ac_source: file not found" "$LINENO" 5 - fi - rm -f "$ac_file" - - # Try a relative symlink, then a hard link, then a copy. - case $ac_source in - [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;; - *) ac_rel_source=$ac_top_build_prefix$ac_source ;; - esac - ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || - ln "$ac_source" "$ac_file" 2>/dev/null || - cp -p "$ac_source" "$ac_file" || - as_fn_error $? "cannot link or copy $ac_source to $ac_file" "$LINENO" 5 - fi - ;; - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "po-directories":C) - for ac_file in $CONFIG_FILES; do - # Support "outfile[:infile[:infile...]]" - case "$ac_file" in - *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - esac - # PO directories have a Makefile.in generated from Makefile.in.in. - case "$ac_file" in */Makefile.in) - # Adjust a relative srcdir. - ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'` - ac_dir_suffix=/`echo "$ac_dir"|sed 's%^\./%%'` - ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'` - # In autoconf-2.13 it is called $ac_given_srcdir. - # In autoconf-2.50 it is called $srcdir. - test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir" - case "$ac_given_srcdir" in - .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;; - /*) top_srcdir="$ac_given_srcdir" ;; - *) top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - # Treat a directory as a PO directory if and only if it has a - # POTFILES.in file. This allows packages to have multiple PO - # directories under different names or in different locations. - if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then - rm -f "$ac_dir/POTFILES" - test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES" - gt_tab=`printf '\t'` - cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ${gt_tab}]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES" - POMAKEFILEDEPS="POTFILES.in" - # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend - # on $ac_dir but don't depend on user-specified configuration - # parameters. - if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then - # The LINGUAS file contains the set of available languages. - if test -n "$OBSOLETE_ALL_LINGUAS"; then - test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete" - fi - ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"` - # Hide the ALL_LINGUAS assignment from automake < 1.5. - eval 'ALL_LINGUAS''=$ALL_LINGUAS_' - POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS" - else - # The set of available languages was given in configure.in. - # Hide the ALL_LINGUAS assignment from automake < 1.5. - eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS' - fi - # Compute POFILES - # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po) - # Compute UPDATEPOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update) - # Compute DUMMYPOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop) - # Compute GMOFILES - # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo) - case "$ac_given_srcdir" in - .) srcdirpre= ;; - *) srcdirpre='$(srcdir)/' ;; - esac - POFILES= - UPDATEPOFILES= - DUMMYPOFILES= - GMOFILES= - for lang in $ALL_LINGUAS; do - POFILES="$POFILES $srcdirpre$lang.po" - UPDATEPOFILES="$UPDATEPOFILES $lang.po-update" - DUMMYPOFILES="$DUMMYPOFILES $lang.nop" - GMOFILES="$GMOFILES $srcdirpre$lang.gmo" - done - # CATALOGS depends on both $ac_dir and the user's LINGUAS - # environment variable. - INST_LINGUAS= - if test -n "$ALL_LINGUAS"; then - for presentlang in $ALL_LINGUAS; do - useit=no - if test "%UNSET%" != "$LINGUAS"; then - desiredlanguages="$LINGUAS" - else - desiredlanguages="$ALL_LINGUAS" - fi - for desiredlang in $desiredlanguages; do - # Use the presentlang catalog if desiredlang is - # a. equal to presentlang, or - # b. a variant of presentlang (because in this case, - # presentlang can be used as a fallback for messages - # which are not translated in the desiredlang catalog). - case "$desiredlang" in - "$presentlang"*) useit=yes;; - esac - done - if test $useit = yes; then - INST_LINGUAS="$INST_LINGUAS $presentlang" - fi - done - fi - CATALOGS= - if test -n "$INST_LINGUAS"; then - for lang in $INST_LINGUAS; do - CATALOGS="$CATALOGS $lang.gmo" - done - fi - test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile" - sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile" - for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do - if test -f "$f"; then - case "$f" in - *.orig | *.bak | *~) ;; - *) cat "$f" >> "$ac_dir/Makefile" ;; - esac - fi - done - fi - ;; - esac - done ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # would make configure fail if this is the last instruction. - $ac_cs_success || as_fn_exit 1 -fi -if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 -$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} -fi - -chmod a+x bin/bout-config - -############################################################# -# Print configuration info -############################################################# - -{ $as_echo "$as_me:${as_lineno-$LINENO}: -------------------------" >&5 -$as_echo "$as_me: -------------------------" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuration summary " >&5 -$as_echo "$as_me: Configuration summary " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: -------------------------" >&5 -$as_echo "$as_me: -------------------------" >&6;} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: PETSc support : $BOUT_HAS_PETSC (has SUNDIALS: $PETSC_HAS_SUNDIALS)" >&5 -$as_echo "$as_me: PETSc support : $BOUT_HAS_PETSC (has SUNDIALS: $PETSC_HAS_SUNDIALS)" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: SLEPc support : $BOUT_HAS_SLEPC" >&5 -$as_echo "$as_me: SLEPc support : $BOUT_HAS_SLEPC" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: IDA support : $BOUT_HAS_IDA" >&5 -$as_echo "$as_me: IDA support : $BOUT_HAS_IDA" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: CVODE support : $BOUT_HAS_CVODE" >&5 -$as_echo "$as_me: CVODE support : $BOUT_HAS_CVODE" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: ARKODE support : $BOUT_HAS_ARKODE" >&5 -$as_echo "$as_me: ARKODE support : $BOUT_HAS_ARKODE" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: FFTW support : $BOUT_HAS_FFTW" >&5 -$as_echo "$as_me: FFTW support : $BOUT_HAS_FFTW" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: NetCDF support : $BOUT_HAS_NETCDF (legacy: $BOUT_HAS_LEGACY_NETCDF)" >&5 -$as_echo "$as_me: NetCDF support : $BOUT_HAS_NETCDF (legacy: $BOUT_HAS_LEGACY_NETCDF)" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Parallel-NetCDF support : $BOUT_HAS_PNETCDF" >&5 -$as_echo "$as_me: Parallel-NetCDF support : $BOUT_HAS_PNETCDF" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Lapack support : $BOUT_HAS_LAPACK" >&5 -$as_echo "$as_me: Lapack support : $BOUT_HAS_LAPACK" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Scorep support : $BOUT_HAS_SCOREP" >&5 -$as_echo "$as_me: Scorep support : $BOUT_HAS_SCOREP" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: OpenMP support : $BOUT_USE_OPENMP (schedule: $OPENMP_SCHEDULE)" >&5 -$as_echo "$as_me: OpenMP support : $BOUT_USE_OPENMP (schedule: $OPENMP_SCHEDULE)" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Natural language support: $BOUT_HAS_GETTEXT (path: $localedir)" >&5 -$as_echo "$as_me: Natural language support: $BOUT_HAS_GETTEXT (path: $localedir)" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: HYPRE support : $BOUT_HAS_HYPRE" >&5 -$as_echo "$as_me: HYPRE support : $BOUT_HAS_HYPRE" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: System UUID generator : $BOUT_HAS_UUID_SYSTEM_GENERATOR" >&5 -$as_echo "$as_me: System UUID generator : $BOUT_HAS_UUID_SYSTEM_GENERATOR" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Enable backtrace : $BOUT_USE_BACKTRACE" >&5 -$as_echo "$as_me: Enable backtrace : $BOUT_USE_BACKTRACE" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Enable color logs : $BOUT_USE_COLOR" >&5 -$as_echo "$as_me: Enable color logs : $BOUT_USE_COLOR" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Enable more debug output: $BOUT_USE_OUTPUT_DEBUG" >&5 -$as_echo "$as_me: Enable more debug output: $BOUT_USE_OUTPUT_DEBUG" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Enable OpenMP : $BOUT_USE_OPENMP" >&5 -$as_echo "$as_me: Enable OpenMP : $BOUT_USE_OPENMP" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Enable FP exceptions : $BOUT_USE_SIGFPE" >&5 -$as_echo "$as_me: Enable FP exceptions : $BOUT_USE_SIGFPE" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Enable signal handlers : $BOUT_USE_SIGNAL" >&5 -$as_echo "$as_me: Enable signal handlers : $BOUT_USE_SIGNAL" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Enable field names : $BOUT_USE_TRACK" >&5 -$as_echo "$as_me: Enable field names : $BOUT_USE_TRACK" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Metric type : $BOUT_METRIC_TYPE" >&5 -$as_echo "$as_me: Metric type : $BOUT_METRIC_TYPE" >&6;} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: -------------------------------" >&5 -$as_echo "$as_me: -------------------------------" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Data analysis configuration " >&5 -$as_echo "$as_me: Data analysis configuration " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: -------------------------------" >&5 -$as_echo "$as_me: -------------------------------" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: === IDL ===" >&5 -$as_echo "$as_me: === IDL ===" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Make sure that the tools/idllib directory is in your IDL_PATH" >&5 -$as_echo "$as_me: Make sure that the tools/idllib directory is in your IDL_PATH" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: e.g. by adding to your ~/.bashrc file" >&5 -$as_echo "$as_me: e.g. by adding to your ~/.bashrc file" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: export IDL_PATH=+$PWD/tools/idllib:'':\$IDL_PATH" >&5 -$as_echo "$as_me: export IDL_PATH=+$PWD/tools/idllib:'':\$IDL_PATH" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: === Python ===" >&5 -$as_echo "$as_me: === Python ===" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: Make sure that the tools/pylib directory is in your PYTHONPATH" >&5 -$as_echo "$as_me: Make sure that the tools/pylib directory is in your PYTHONPATH" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: e.g. by adding to your ~/.bashrc file" >&5 -$as_echo "$as_me: e.g. by adding to your ~/.bashrc file" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: export PYTHONPATH=$PWD/tools/pylib/:\$PYTHONPATH" >&5 -$as_echo "$as_me: export PYTHONPATH=$PWD/tools/pylib/:\$PYTHONPATH" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: *** Now run '$MAKE' to compile BOUT++ ***" >&5 -$as_echo "$as_me: *** Now run '$MAKE' to compile BOUT++ ***" >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: " >&5 -$as_echo "$as_me: " >&6;} -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ./configure is deprecated and will be removed in a future version, please use CMake instead" >&5 -$as_echo "$as_me: WARNING: ./configure is deprecated and will be removed in a future version, please use CMake instead" >&2;} diff --git a/configure.ac b/configure.ac deleted file mode 100644 index 0bacd1097a..0000000000 --- a/configure.ac +++ /dev/null @@ -1,1499 +0,0 @@ -# Copyright 2010 B D Dudson, S Farley -# -# Contact Ben Dudson, bd512@york.ac.uk -# -# This file is part of BOUT++. -# -# BOUT++ is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# BOUT++ 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 Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with BOUT++. If not, see . -# -##################################################################### -# -# Process this file with autoreconf to produce a configure script. -# -# $ autoreconf -if -# -# Changelog: -# -# 2010-03-09 Ben Dudson -# * Changing to always require FFTW (removing NR routines) -# 2015-08-08 David Schwörer -# * Searching for libs in lib and lib64 -# - -AC_PREREQ([2.69]) -AC_INIT([BOUT++],[5.1.0],[bd512@york.ac.uk]) -AC_CONFIG_AUX_DIR([build-aux]) -AC_CONFIG_MACRO_DIR([m4]) - -AC_MSG_WARN([./configure is deprecated and will be removed in a future version, please use CMake instead]) - -AC_ARG_WITH(netcdf, [AS_HELP_STRING([--with-netcdf], - [Enable support for netCDF files])],,[]) -AC_ARG_WITH(pnetcdf, [AS_HELP_STRING([--with-pnetcdf], - [Set path to Parallel NetCDF library])],,[]) -AC_ARG_WITH(ida, [AS_HELP_STRING([--with-ida=/path/to/ida], - [Use the SUNDIALS IDA solver])],,[]) -AC_ARG_WITH(cvode, [AS_HELP_STRING([--with-cvode], - [Use the SUNDIALS CVODE solver])],,[]) -AC_ARG_WITH(sundials, [AS_HELP_STRING([--with-sundials], - [Use CVODE and IDA])],,[]) -AC_ARG_WITH(fftw, [AS_HELP_STRING([--with-fftw], - [Set directory of FFTW3 library])],,[]) -AC_ARG_WITH(lapack, [AS_HELP_STRING([--with-lapack], - [Use the LAPACK library])],,[with_lapack=guess]) -AC_ARG_WITH(petsc, [AS_HELP_STRING([--with-petsc], - [Enable PETSc interface])],,[with_petsc=no]) -AC_ARG_WITH(slepc, [AS_HELP_STRING([--with-slepc], - [Enable SLEPc interface])],,[with_slepc=no]) -AC_ARG_WITH(pvode, [AS_HELP_STRING([--with-pvode], - [Build and enable PVODE 98 (DEFAULT)])],,[]) -AC_ARG_WITH(arkode, [AS_HELP_STRING([--with-arkode], - [Use the SUNDIALS ARKODE solver])],,[]) -AC_ARG_WITH(scorep, [AS_HELP_STRING([--with-scorep], - [Enable support for scorep based instrumentation])],,[with_scorep=no]) -AC_ARG_WITH(hypre, [AS_HELP_STRING([--with-hypre], - [Enable support for HYPRE])],,[with_hypre=no]) - -dnl --with-hdf5 flags are set in AX_LIB_{PARALLEL}HDF5 -AC_ARG_WITH(system_mpark, [AS_HELP_STRING([--with-system-mpark], - [Use mpark.variant already installed rather then the bundled one])],,[with_system_mpark=auto]) -AC_ARG_WITH(system_uuid, [AS_HELP_STRING([--with-system-uuid], - [Use libuuid to generate UUIDs])],,[with_system_uuid=auto]) - -AC_ARG_ENABLE(warnings, [AS_HELP_STRING([--disable-warnings], - [Disable compiler warnings])],,[]) -AC_ARG_ENABLE(checks, [AS_HELP_STRING([--enable-checks=no/1/2/3], - [Set run-time checking level])],,[enable_checks=default]) -AC_ARG_ENABLE(msgstack, [AS_HELP_STRING([--enable-msgstack=no/yes], - [Enable MstStack for backtrace. Default based on check level.])],,[enable_msgstack=maybe]) -AC_ARG_ENABLE(signal, [AS_HELP_STRING([--disable-signal], - [Disable SEGFAULT handling])],,[]) -AC_ARG_ENABLE(color, [AS_HELP_STRING([--disable-color], - [Disable -c option to color output])],,[]) -AC_ARG_ENABLE(track, [AS_HELP_STRING([--enable-track], - [Enable variable tracking])],,[]) -AC_ARG_ENABLE(debug, [AS_HELP_STRING([--enable-debug], - [Enable all debugging flags])],,[]) -AC_ARG_ENABLE(output_debug, [AS_HELP_STRING([--enable-output-debug], - [Enable some extra debugging output])],,[]) -AC_ARG_ENABLE(optimize, [AS_HELP_STRING([--enable-optimize=no/1/2/3/4], - [Enable optimization])],,[]) -AC_ARG_ENABLE(sigfpe, [AS_HELP_STRING([--enable-sigfpe], - [Enable FloatingPointExceptions])],,[]) -AC_ARG_ENABLE(backtrace, [AS_HELP_STRING([--disable-backtrace], - [Disable function backtrace])],,[enable_backtrace=maybe]) -AC_ARG_ENABLE(shared, [AS_HELP_STRING([--enable-shared], - [Enable building bout++ into an shared object])],,[enable_shared=no]) -AC_ARG_ENABLE(static, [AS_HELP_STRING([--enable-static], - [Enable building bout++ into an static library])],,[enable_static=auto]) -AC_ARG_ENABLE(openmp, [AS_HELP_STRING([--enable-openmp], - [Enable building with OpenMP support])],,[enable_openmp=no]) -AC_ARG_WITH(openmp_schedule,[AS_HELP_STRING([--with-openmp-schedule=static/dynamic/guided/auto], - [Set OpenMP schedule (default: static)])],,[with_openmp_schedule=static]) -AC_ARG_ENABLE(pvode_openmp, [AS_HELP_STRING([--enable-pvode-openmp], - [Enable building PVODE with OpenMP support])],,[enable_pvode_openmp=no]) -AC_ARG_ENABLE(metric_3d, [AS_HELP_STRING([--enable-metric-3d], - [Use Field3D to store coordinates metric data])],,[enable_metric_3d=no]) - -AC_ARG_VAR(EXTRA_INCS,[Extra compile flags]) -AC_ARG_VAR(EXTRA_LIBS,[Extra linking flags]) - -file_formats="" # Record which file formats are being supported - -# Delete the build log from last time -rm -f config-build.log - -# only keep BOUT related undefs -if ! grep -q 'NOTE TO DEVEL' autoconf_build_defines.hxx.in ; then - grep 'undef BOUT' -B 4 -A 1 autoconf_build_defines.hxx.in > autoconf_build_defines.hxx.in.tmp - echo '// NOTE TO DEVELOPERS: PLEASE KEEP THIS LINE AND DELETE AUTOGENERATED CONTENT BELOW!' >> autoconf_build_defines.hxx.in.tmp - mv autoconf_build_defines.hxx.in.tmp autoconf_build_defines.hxx.in -fi - - -AC_ARG_VAR(CXXFLAGS,[Extra compile flags]) -AC_ARG_VAR(LDFLAGS,[Extra linking flags]) -AC_ARG_VAR(LIBS,[Extra linking libraries]) -LIBS="$LIBS $LDLIBS" - -AC_SUBST(MKDIR_P) -AC_SUBST(EXTRA_INCS) -AC_SUBST(EXTRA_LIBS) - -# Adding variables for additional sources -AC_SUBST(PRECON_SOURCE) - -# We're using C++ -AC_LANG(C++) - -############################################################# -# Checks for programs -############################################################# - -# Autoconf inserts "-g -O2" into flags by default -# Set them to be just "-g", but only if the user hasn't already set CXXFLAGS -# We then put "-O2" back in later, assuming optimisations aren't explicitly disabled -: ${CXXFLAGS="-g"} - -# Search for MPI compiler; fail if not found -AX_PROG_CXX_MPI([], [], [ - AC_MSG_ERROR([*** An MPI compiler is required. You might need to set MPICXX correctly.]) -]) - -# Utility programs -AC_PROG_MKDIR_P -AC_PROG_LN_S -AC_PROG_MAKE_SET -AC_PROG_INSTALL - -# Set MAKE to gmake if possible, otherwise make -AC_CHECK_PROG(MAKE, gmake, gmake, make) - -AC_PROG_RANLIB - -AC_SUBST(ARFLAGS) - -ARFLAGS='' -for flag in cruU cru -do - echo 1 > artest1 - ar $flag artest artest1 &&ar $flag artest artest1 - arexit=$? - rm -f artest1 artest - if test $arexit -eq 0 - then - ARFLAGS="$flag" - break; - fi -done -test -z $ARFLAGS && AC_MSG_ERROR([Failed to find suitable flags for ar]) - -# Check for and enable C++14 support -# Error if not supported -AX_CXX_COMPILE_STDCXX([14], [noext], [mandatory]) - -############################################################# -# STD Library functions -############################################################# - -# Checks for libraries. -AC_CHECK_LIB([m], [sqrt]) - -# Checks for header files. -AC_HEADER_STDC -AC_CHECK_HEADERS([malloc.h stdlib.h string.h strings.h]) - -# Checks for library functions. -AC_FUNC_MALLOC -AC_FUNC_REALLOC -AC_FUNC_VPRINTF - -# Check for OpenMP support -: ${enable_openmp=no} # Disable by default -AC_OPENMP -BOUT_USE_OPENMP=$enable_openmp - -BOUT_OPENMP_SCHEDULE=$with_openmp_schedule - -# Check if we have access to __PRETTY_FUNCTION__ -BOUT_CHECK_PRETTYFUNCTION - -############################################################# -# Code coverage using gcov -# -# Mutally exclusive with optimisation, therefore needs to come first -# so we can turn off optimisation if coverage is enabled -############################################################# - -AX_CODE_COVERAGE() -AS_IF([test "x$enable_code_coverage" = "xyes"], -[ - AS_IF([test "x$enable_optimize"], [ - AC_MSG_WARN([Code coverage clashes with optimisations, disabling optimisations]) - enable_optimize="no" - ]) - COVERAGE_FLAGS="--coverage --no-inline" - LDFLAGS="$LDFLAGS --coverage" -], [ - COVERAGE_FLAGS= -]) -AC_SUBST([COVERAGE_FLAGS]) - -############################################################# -# General Options -############################################################# - -# Always pass -Werror=unknown-warning-option to get Clang to fail on bad -# flags, otherwise they are always appended to the warn_cxxflags variable, -# and Clang warns on them for every compilation unit. -# If this is passed to GCC, it will explode, so the flag must be enabled -# conditionally. -# This check taken from AX_COMPILER_FLAGS_CXXFLAGS -extra_compiler_flags_test="" -AX_CHECK_COMPILE_FLAG([-Werror=unknown-warning-option],[ - extra_compiler_flags_test="-Werror=unknown-warning-option" -]) -# A similar check to above, but for Intel. -we is undocumented, but -# the equivalent (?) -diag-error gets accepted by GCC. 10006 is -# "unknown option", and 10148 is the more recent "unknown warning -# option" -AX_CHECK_COMPILE_FLAG([-we10006,10148],[ - extra_compiler_flags_test="-we10006,10148" -]) - -AS_IF([test "x$enable_warnings" != "xno"], [ -# Some hopefully sensible default compiler warning flags - - AX_APPEND_COMPILE_FLAGS([ dnl - -Wall dnl - -Wextra dnl - -Wnull-dereference dnl - ], [CXXFLAGS], [$extra_compiler_flags_test]) - -# Note we explicitly turn off -Wcast-function-type as PETSc *requires* -# we cast a function to the wrong type in MatFDColoringSetFunction - -# Also note that gcc ignores unknown flags of the form "-Wno-warning" -# for backwards compatibility. Therefore we need to add the positive -# form as an additional flag which it will choke on (if it doesn't -# exist). See: https://gcc.gnu.org/wiki/FAQ#wnowarning - - AX_APPEND_COMPILE_FLAGS([ dnl - -Wno-cast-function-type dnl - ], [CXXFLAGS], [$extra_compiler_flags_test "-Wcast-function-type"]) - -], [ - AC_MSG_NOTICE([Compiler warnings disabled]) -]) - -OPT_FLAGS="" -enable_checks_def=2 -AS_IF([test "$enable_debug" != ""], [ - AC_MSG_NOTICE([Enabling all debug options]) - enable_checks_def=3 - # use -Og with available, otherwise fall back to -O0 - OPT_FLAGS="-g -O0 -Og -fno-inline -hipa1" -], [ - AS_IF([test "x$enable_optimize" != "xno"], [ - AS_CASE(["$enable_optimize"], - ["default" | "yes" | ""], - [AC_MSG_NOTICE([Enabling default optimisations]) - OPT_FLAGS="-O2"], - ["fast" | "4"], - [AC_MSG_NOTICE([Enabling level 4 optimisations]) - OPT_FLAGS="-Ofast -fno-finite-math-only -march=native -funroll-loops" - enable_checks_def=0], - ["3"], - [AC_MSG_NOTICE([Enabling level 3 optimisations]) - OPT_FLAGS="-O3 -march=native -funroll-loops" - enable_checks_def=0], - ["2"], - [AC_MSG_NOTICE([Enabling level 2 optimisations]) - OPT_FLAGS="-O2 -march=native" - enable_checks_def=1], - ["1" | "0"], - [AC_MSG_NOTICE([Enabling level $enable_optimize optimisations]) - OPT_FLAGS="-O$enable_optimize"], - [ - AC_MSG_ERROR([unrecognized option: --enable-optimize=$enable_optimize]) - ]) - ], [OPT_FLAGS=""]) -]) - -# Append optimisation/debug flags if they work with this compiler -AX_APPEND_COMPILE_FLAGS([ dnl - $OPT_FLAGS dnl -], [CXXFLAGS], [$extra_compiler_flags_test]) - -# Disable checks if optimization > 2 is used -AS_IF([test "x$enable_checks" = "xdefault" ], [ - enable_checks=$enable_checks_def -]) - -BOUT_CHECK_LEVEL=0 -AS_IF([test "x$enable_checks" != "xno" && test "x$enable_checks" != "x0"], [ - AC_MSG_NOTICE([Run-time checking enabled]) - AS_CASE([$enable_checks], - [1], [AC_MSG_NOTICE([ -> Level 1 (Basic checking)]) - CXXFLAGS="$CXXFLAGS -DCHECK=1" - BOUT_CHECK_LEVEL=1], - [3], [AC_MSG_NOTICE([ -> Level 3 (Full checking)]) - enable_output_debug=yes - CXXFLAGS="$CXXFLAGS -DCHECK=3" - BOUT_CHECK_LEVEL=3], - [AC_MSG_NOTICE([ -> Level 2 (Enhanced checking)]) - CXXFLAGS="$CXXFLAGS -DCHECK=2" - BOUT_CHECK_LEVEL=2]) -], [ - AC_MSG_NOTICE([Run-time checking disabled]) -]) - -BOUT_USE_MSGSTACK=$(test $BOUT_CHECK_LEVEL -gt 1 && echo yes || echo no) -AS_IF([test "x$enable_msgstack" = "xyes" ], [ - BOUT_USE_MSGSTACK=yes -], [ - AS_IF([test "x$enable_msgstack" = "xno" ], [ - BOUT_USE_MSGSTACK=no - ], []) -]) -AS_IF([test $BOUT_USE_MSGSTACK = no ], [ - AC_MSG_NOTICE([Stack tracing disabled]) -], [ - AC_MSG_NOTICE([Stack tracing enabled]) -]) - -BOUT_USE_SIGNAL=no -AS_IF([test "x$enable_signal" != "xno"], [ - AC_MSG_NOTICE([Segmentation fault handling enabled]) - BOUT_USE_SIGNAL=yes -], [ - AC_MSG_NOTICE([Segmentation fault handling disabled]) -]) - -BOUT_USE_COLOR=no -AS_IF([test "x$enable_color" != "xno"], [ - AC_MSG_NOTICE([Output coloring enabled]) - BOUT_USE_COLOR=yes -], [ - AC_MSG_NOTICE([Output coloring disabled]) -]) - -BOUT_USE_TRACK=no -AS_IF([test "x$enable_track" = "xyes"], [ - AC_MSG_NOTICE([Field name tracking enabled]) - BOUT_USE_TRACK=yes -], [ - AC_MSG_NOTICE([Field name tracking disabled]) -]) - -BOUT_USE_SIGFPE=no -AS_IF([test "x$enable_sigfpe" = "xyes"], [ - AC_MSG_NOTICE([Signaling floating point exceptions enabled]) - BOUT_USE_SIGFPE=yes -], [ - AC_MSG_NOTICE([Signaling floating point exceptions disabled]) -]) - -BOUT_USE_OUTPUT_DEBUG=no -AS_IF([test "x$enable_output_debug" = "xyes"], [ - AC_MSG_NOTICE([Extra debug output enabled]) - BOUT_USE_OUTPUT_DEBUG=yes -], [ - AC_MSG_NOTICE([Extra debug output disabled]) -]) - -BOUT_VERSION=$PACKAGE_VERSION -BOUT_VERSION_MAJOR=$(echo $PACKAGE_VERSION | cut -d. -f1) -BOUT_VERSION_MINOR=$(echo $PACKAGE_VERSION | cut -d. -f2) -BOUT_VERSION_PATCH=$(echo ${PACKAGE_VERSION%-*} | cut -d. -f3) -BOUT_VERSION_TAG=$(echo $PACKAGE_VERSION | cut -d- -f2) - -############################################################# -# Enable Backtrace if possible -############################################################# - -BOUT_USE_BACKTRACE=no -AS_IF([test "x$enable_backtrace" = "xyes" || test "x$enable_backtrace" = "xmaybe"], [ - AC_CHECK_PROG([works], [addr2line], [yes], [no]) - - AS_IF([test $works = yes], [ - AC_CHECK_FUNCS([popen backtrace], [works=yes], [works=no; break]) - ]) - - AS_IF([test $works = yes], [ - AC_CHECK_HEADERS([execinfo.h dlfcn.h], [works=yes], [works=no; break]) - ]) - - AS_IF([test $works = yes], [ - AC_SEARCH_LIBS([dladdr], [dl], [works=yes], [works=no; break]) - ]) - - AS_IF([test $works = yes], [ - AC_MSG_NOTICE([Native backtrace enabled]) - BOUT_USE_BACKTRACE=yes - ], [ - AS_IF([test "x$enable_backtrace" = "xyes"], [ - AC_MSG_ERROR([backtrace requested, but cannot be enabled]) - ], [ - AC_MSG_WARN([Native backtrace disabled]) - ]) - ]) -]) - -AS_IF([test "x$enable_metric_3d" != "xno"], [ - AC_MSG_WARN([Using Field3D to store coordinates data, this is experimental.]) - BOUT_METRIC_TYPE="3D" -], [ - AC_MSG_NOTICE([Using Field2D to store coordinates data]) - BOUT_METRIC_TYPE="2D" -]) - -############################################################# -# Build into shared object (pic) -############################################################# - -LIB_TO_BUILD='' -AS_IF([test "x$enable_shared" = "xyes"], [ - # compile as position independent code. - # -fpic is apparently faster then -fPIC, but -fPIC works always. - # From a SO comment (https://stackoverflow.com/a/3544211/3384414): - # What's more: I did a little experiment here (on x86_64 - # platform), -fPIC and -fpic appears to have generated the same - # code. It seems they generate a different code only on m68k, - # PowerPC and SPARC. - # Therfore use -fPIC for now - CXXFLAGS="$CXXFLAGS -fPIC" - LIB_TO_BUILD="$LIB_TO_BUILD"' $(BOUT_LIB_PATH)/libbout++.so' - AS_IF([test "x$enable_static" = "xauto"], [ - enable_static=no - ]) - SHARED_EXTRA=':' - AS_IF([test "x$enable_static" = "xno"], [ - SHARED_EXTRA='$(RM) -f $(BOUT_LIB_PATH)/libbout++.a' - ]) -], [ - AS_IF([test "x$enable_static" = "xauto"], [ - enable_static=yes - ]) -]) - -AS_IF([test "x$enable_static" = "xyes"], [ - LIB_TO_BUILD="$LIB_TO_BUILD"' $(BOUT_LIB_PATH)/libbout++.a' - STATIC_EXTRA=':' - # In case we only build static, make sure shared libs are removed - AS_IF([! test "x$enable_shared" = "xyes"], [ - STATIC_EXTRA='$(RM) -f $(BOUT_LIB_PATH)/*.so*' - ]) -]) - -AS_IF([test "x$LIB_TO_BUILD" = x ], [ - AC_MSG_ERROR([Need to enable at least one of static or shared!]) -]) - -############################################################# -# Git revision number -############################################################# - -rev=`git rev-parse HEAD` -AS_IF([test $? = 0], [ - AC_MSG_NOTICE([Git revision: $rev]) - BOUT_REVISION=$rev -], [ - BOUT_REVISION= -]) - -############################################################# -# FFT routines -############################################################# - -AS_IF([test "x$with_fftw" != "xno"], [ -AC_PATH_PROG([fftw_path], [fftw-wisdom], [no], [$with_fftw$PATH_SEPARATOR$PATH]) - - AS_IF([test "x$fftw_path" != "xno"], [ - fftw_wisdom0=`AS_DIRNAME(["$fftw_path"])` - fftw_wisdom=`AS_DIRNAME(["$fftw_wisdom0"])` - with_fftw="$with_fftw $fftw_wisdom" - ], AC_MSG_NOTICE([FFTW3 requested but fftw-wisdom not found])) - - BOUT_ADDPATH_CHECK_HEADER(fftw3.h, ,AC_MSG_ERROR([FFTW3 requested but header not found]), $with_fftw) - BOUT_ADDPATH_CHECK_LIB(fftw3, fftw_plan_dft_r2c_1d, ,AC_MSG_ERROR([FFTW3 requested but library not found]), $with_fftw) - - BOUT_HAS_FFTW="yes" -], -[ -AC_MSG_NOTICE([Configuring without FFTW3 is not recommended]) -BOUT_HAS_FFTW="no" -]) - -############################################################# -# netCDF support -############################################################# - -NCCONF="" # Configuration script - -BOUT_HAS_NETCDF=no -BOUT_HAS_LEGACY_NETCDF=no -AS_IF([test "x$with_netcdf" != "xno"], -[ - ########################################## - # Try to find a valid NetCDF configuration - # - # at first, try to find ncconf script - - # Search for NetCDF config scripts, prefer ncxx4-config over nc-config - # Check if the path to the config script has been supplied directly, otherwise - # check the path provided by --with-netcdf, appending "/bin" if need - # be, then check system path - # Set NCCONF to the full path of the found scropt - AS_CASE([`basename $with_netcdf 2> /dev/null`], - ["ncxx4-config"], [NCCONF=$with_netcdf], - ["nc-config"], [NCCONF=$with_netcdf], - [AC_PATH_PROGS([NCCONF], [ncxx4-config nc-config], [], - [$with_netcdf$PATH_SEPARATOR$with_netcdf/bin$PATH_SEPARATOR$PATH])]) - - ########################################## - # Get configuration - AS_IF([test "x$NCCONF" != "x" ], - [ - # If we found nc-config rather than ncxx4-config, we need to check if it supports C++ - AS_IF([test `basename $NCCONF` = 'nc-config'], - [AC_MSG_CHECKING([if $NCCONF has C++4 support]) - nc_has_cpp4=`$NCCONF --has-c++4` - AC_MSG_RESULT([$nc_has_cpp4]) - AC_MSG_CHECKING([if $NCCONF has C++ support]) - nc_has_cpp=`$NCCONF --has-c++` - AC_MSG_RESULT([$nc_has_cpp]) - ], [ - nc_has_cpp4="yes" - ]) - - NCINC=`$NCCONF --cflags` - EXTRA_INCS="$EXTRA_INCS $NCINC" - AS_IF([test "x$nc_has_cpp4" = "xyes"], - [ - NCLIB=`$NCCONF --libs` - BOUT_HAS_NETCDF=yes - AC_MSG_NOTICE([ -> NetCDF-4 support enabled]) - ], [ - # nc-config might not *say* it has C++ support, but we can try anyway - AC_MSG_CHECKING([if we can compile NetCDF with C++]) - # Note netcdf_c++ needed - NCLIB=`$NCCONF --libs | sed s/-lnetcdf/-lnetcdf_c++\ -lnetcdf/` - - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CXXFLAGS=$CXXFLAGS - AC_LANG_PUSH([C++]) - LIBS="$save_LIBS $NCLIB" - LDFLAGS="$save_LDFLAGS $NCLIB" - CXXFLAGS="$save_CXXFLAGS $NCINC" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([ - #include - ], [NcFile file("foo.nc");])], - [AC_MSG_RESULT([yes]) - AC_MSG_NOTICE([ -> Legacy NetCDF support enabled])], - [AC_MSG_RESULT([no]) - AC_MSG_FAILURE([*** Could not compile NetCDF C++ program!])]) - AC_LANG_POP([C++]) - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CXXFLAGS="$save_CXXFLAGS" - BOUT_HAS_NETCDF=yes - BOUT_HAS_LEGACY_NETCDF=yes - ]) - EXTRA_LIBS="$EXTRA_LIBS $NCLIB" - - file_formats="$file_formats netCDF" - NCPATH="found" - NCFOUND=yes - ], [ - # if nc-config / ncxx4-config is not found, try to find library directly - BOUT_MSG_DEBUG([calling bout addpath]) - BOUT_ADDPATH_CHECK_HEADER(netcdfcpp.h, - BOUT_ADDPATH_CHECK_LIB(netcdf, nc_get_att, - BOUT_ADDPATH_CHECK_LIB(netcdf_c++, nc_close, NCFOUND=yes, NCFOUND=no, [$with_netcdf]), - NCFOUND=no, [$with_netcdf]), - NCFOUND=no, [$with_netcdf]) - - AS_IF([test "x$NCFOUND" = "xyes"], - [ - file_formats="$file_formats netCDF" - AC_MSG_NOTICE([ -> Legacy NetCDF support enabled]) - NCPATH="found" - BOUT_HAS_NETCDF=yes - BOUT_HAS_LEGACY_NETCDF=yes - ], []) - ]) - - AS_IF([test $with_netcdf && test "x$NCFOUND" != "xyes" ], AC_MSG_ERROR([NetCDF requested but not found]), []) - AS_IF([test "x$NCFOUND" != "xyes"], [AC_MSG_NOTICE([ -> NetCDF support disabled])], []) -], []) - -############################################################# -# Parallel NetCDF support -############################################################# - -PNCPATH="" -AS_IF([test "$with_pnetcdf" != "no" && test "x$with_pnetcdf" != "x" ], [ - AC_MSG_NOTICE([Searching for Parallel-NetCDF library]) - - AS_IF([test "x$with_pnetcdf" != "xyes"], [ - # Given a path to the library - AC_CHECK_FILES([$with_pnetcdf/include/pnetcdf.h], [PNCPATH=$with_pnetcdf], - AC_MSG_NOTICE([parallel-netcdf not found in given directory]) - ) - ]) - - # Find the utilities included with pnetcdf - AS_IF([test "x$PNCPATH" = "x"], [ - AS_IF([test "x$with_pnetcdf" = "xyes"], [ - AC_PATH_PROG([NCMPIDUMP_PATH], [ncmpidump]) - ], [ - AC_PATH_PROG([NCMPIDUMP_PATH], [ncmpidump], [$with_pnetcdf$PATH_SEPARATOR$PATH]) - ]) - AS_IF([test "$NCMPIDUMP_PATH" != ""], [ - AC_CHECK_FILES([$NCMPIDUMP_PATH/../include/pnetcdf.h], [PNCPATH=$NCMPIDUMP_PATH/../]) - ]) - ]) - - AS_IF([test "x$PNCPATH" != "x"], [ - AC_CHECK_FILES($path/lib/libpnetcdf.a, PNCPATHLIB='lib', - AC_CHECK_FILES($path/lib64/libpnetcdf.a, PNCPATHLIB='lib64', PNCPATH='')) - ]) - - AS_IF([test "x$PNCPATH" = "x" && test "x$with_pnetcdf" != "x"], [ - AC_MSG_FAILURE([*** Parallel-NetCDF requested but not found]) - ]) -]) - -AS_IF([test "x$PNCPATH" = "x"], [ - AC_MSG_NOTICE([Parallel-NetCDF support disabled]) -], [ - # Set a compile-time flag - CXXFLAGS="$CXXFLAGS -DPNCDF" - EXTRA_INCS="$EXTRA_INCS -I$PNCPATH/include" - EXTRA_LIBS="$EXTRA_LIBS -L$PNCPATH/$PNCPATHLIB -lpnetcdf" - - file_formats="$file_formats Parallel-NetCDF" - AC_MSG_NOTICE([Parallel-NetCDF support enabled]) -]) - -############################################################# -# Check file formats -############################################################# - -AS_IF([test "x$file_formats" = "x"], [ - AC_MSG_ERROR([*** At least one file format must be supported]) -], [ - AC_MSG_NOTICE([Supported file formats:$file_formats]) -]) - -############################################################# -# LAPACK routines (Used for tri- and band-diagonal solvers) -############################################################# - -BOUT_HAS_LAPACK="no" -AS_IF([test "x$with_lapack" != "xno"], [ - AS_IF([test "x$with_lapack" = "xguess" || test "x$with_lapack" = "x" ], - [lapack_path=""], - [AS_IF([test "x$with_lapack" != xyes], - [lapack_path=$with_lapack - with_lapack=yes], - [lapack_path=""]) - ]) - BOUT_ADDPATH_CHECK_LIB(blas, zgemm_, - [BOUT_HAS_BLAS=yes], - [AS_IF([test "x$with_lapack" = "xyes"], - AC_MSG_ERROR([LAPACK requested but couldn't find BLAS]))], - $lapack_path) - BOUT_ADDPATH_CHECK_LIB(lapack, zgbsv_, - [BOUT_HAS_LAPACK=yes - AC_MSG_NOTICE([Using LAPACK]) - ], - [AS_IF([test "x$with_lapack" = "xyes"], - AC_MSG_ERROR([LAPACK requested but not found]))], - $lapack_path) -]) - -############################################################# -# PETSc library -############################################################# - -AS_IF([test "x$with_petsc" != "x" && test "$with_petsc" != "no"], [ - -# Supplying an argument to "--with-petsc" only works if PETSC_ARCH -# *should* be empty. If it should be non-empty, THIS WILL NOT WORK - AS_IF([test "$with_petsc" != "yes"], [ - PETSC_DIR="$with_petsc" - PETSC_ARCH= - ]) - - AC_MSG_NOTICE([Using PETSC_DIR=$PETSC_DIR, PETSC_ARCH=$PETSC_ARCH]) - -# Define a macro for a nice error message that preserves the -# formatting. Use like: -# -# PETSC_ERROR_MESSAGE -# -# with no identation - m4_define(PETSC_ERROR_MESSAGE, - [ You may need to specify PETSC_DIR and PETSC_ARCH like so: - --with-petsc PETSC_DIR=\$PETSC_DIR PETSC_ARCH=\$PETSC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#petsc - ]) - -# PETSc changed the location of the conf directory in 3.5, so we -# need to check both locations -# If we find nether, try to fall back to pkg-conf - PETSC_PKGCONF=no - AC_CHECK_FILE($PETSC_DIR/$PETSC_ARCH/conf, [ - PETSC_CONFDIR=${PETSC_DIR}/conf - ], [ - AC_CHECK_FILE($PETSC_DIR/$PETSC_ARCH/lib/petsc/conf, [ - PETSC_CONFDIR=${PETSC_DIR}/lib/petsc/conf - ], [ - PKG_CHECK_MODULES(PETSC, PETSc >= 3.4.0 , - PETSC_PKGCONF=yes, [ - PKG_CHECK_MODULES(PETSC, petsc >= 3.4.0 , - PETSC_PKGCONF=yes, [ - AC_MSG_ERROR([--with-petsc was specified but could not find PETSc distribution. -PETSC_ERROR_MESSAGE]) - ]) - ]) - ]) - ]) - - AS_IF([test $PETSC_PKGCONF = no] , - [ -# We've found an installation, need to check we can use it. First we -# need to be able to check the version number, for which we need -# petscverion.h - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I$PETSC_DIR/include" - AC_CHECK_HEADER([petscversion.h], - [FOUND_PETSC_HEADER=yes], - [FOUND_PETSC_HEADER=no] - ) - -# This is a terrible hack for some Linux distributions (Fedora) that -# install PETSc in a non-supported fashion. This is really the fault -# of PETSc for their weird method of installation - AS_IF([test $FOUND_PETSC_HEADER = no], [ - AC_CHECK_FILE([${PETSC_CONFDIR}/petscvariables], [], [ - AC_MSG_ERROR([Unable to find either petscversion.h or petscvariables -PETSC_ERROR_MESSAGE]) - ]) - -# This relies on the assumption that PETSC_ARCH is empty - PETSC_CC_INCLUDES=$(grep ^PETSC_CC_INCLUDES ${PETSC_CONFDIR}/petscvariables | cut -d= -f 2-) - - AC_MSG_NOTICE([Looking for petscverion.h using $PETSC_CC_INCLUDES from ${PETSC_CONFDIR}/petscvariables]) - - # This is the cache variable set by the previous call to - # AC_CHECK_HEADER. We need to unset it so we can call the macro - # again, but now with different CPPFLAGS - AS_UNSET([ac_cv_header_petscversion_h]) - - CPPFLAGS="$CPPFLAGS $PETSC_CC_INCLUDES" - AC_CHECK_HEADER([petscversion.h], [], [ - AC_MSG_ERROR([Couldn't find or include petscversion.h. -PETSC_ERROR_MESSAGE]) - ]) - ], []) - -# Now we have the header we want, we can check the version number - AC_MSG_CHECKING([PETSc is at least 3.4.0]) - AC_EGREP_CPP([yes], [ - #include - #if PETSC_VERSION_GE(3, 4, 0) - yes - #endif - ], [PETSC_VERSION_OK="yes"], - [PETSC_VERSION_OK="no"]) - AC_MSG_RESULT([$PETSC_VERSION_OK]) - CPPFLAGS="$save_CPPFLAGS" - - AS_IF([test $PETSC_VERSION_OK = no], [ - AC_MSG_ERROR([PETSc version must be at least 3.4.0]) - ]) - -# Check if PETSc was compiled with SUNDIALS - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I$PETSC_DIR/$PETSC_ARCH/include" - AC_MSG_CHECKING([PETSc has SUNDIALS support]) - AC_EGREP_CPP([yes], [ - #include - #ifdef PETSC_HAVE_SUNDIALS - yes - #endif - ], [PETSC_HAS_SUNDIALS="yes"], - [PETSC_HAS_SUNDIALS="no"]) - AC_MSG_RESULT([$PETSC_HAS_SUNDIALS]) - CPPFLAGS="$save_CPPFLAGS" - - AS_IF([test "$PETSC_HAS_SUNDIALS" = "yes"], [ - CXXFLAGS="$CXXFLAGS -DPETSC_HAS_SUNDIALS " - ]) - - # Set the line to be included in the make.conf file - PETSC_MAKE_INCLUDE="include ${PETSC_CONFDIR}/variables" - - BOUT_HAS_PETSC="yes" - - EXTRA_INCS="$EXTRA_INCS \$(PETSC_CC_INCLUDES)" - EXTRA_LIBS="$EXTRA_LIBS \$(PETSC_LIB)" - ], [ dnl pkg-config version - - # Check if PETSc was compiled with SUNDIALS - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $PETSC_CFLAGS" - AC_MSG_CHECKING([PETSc has SUNDIALS support]) - AC_EGREP_CPP([yes], [ - #include - #ifdef PETSC_HAVE_SUNDIALS - yes - #endif - ], [PETSC_HAS_SUNDIALS="yes"], - [PETSC_HAS_SUNDIALS="no"]) - AC_MSG_RESULT([$PETSC_HAS_SUNDIALS]) - CPPFLAGS="$save_CPPFLAGS" - - AS_IF([test "$PETSC_HAS_SUNDIALS" = "yes"], [ - CXXFLAGS="$CXXFLAGS -DPETSC_HAS_SUNDIALS " - ]) - PETSC_MAKE_INCLUDE= - BOUT_HAS_PETSC="yes" - - EXTRA_INCS="$EXTRA_INCS $PETSC_CFLAGS" - EXTRA_LIBS="$PETSC_LIBS $EXTRA_LIBS" - ]) -], [ - PETSC_MAKE_INCLUDE= - BOUT_HAS_PETSC="no" - PETSC_HAS_SUNDIALS="no" -]) - -############################################################# -# SLEPc library -############################################################# - -AS_IF([test "x$with_slepc" != "x" && test "$with_slepc" != "no"], [ - - AS_IF([test $BOUT_HAS_PETSC = "no"], [ - AC_MSG_ERROR([--with-slepc specified, but no PETSc detected. Please reconfigure and specify --with-petsc -PETSC_ERROR_MESSAGE]) - ]) - -# Supplying an argument to "--with-slepc" only works if SLEPC_ARCH -# *should* be empty. If it should be non-empty, THIS WILL NOT WORK - AS_IF([test "$with_slepc" != "yes"], [ - SLEPC_DIR="$with_slepc" - SLEPC_ARCH= - ]) - - AC_MSG_NOTICE([Using SLEPC_DIR=$SLEPC_DIR, SLEPC_ARCH=$SLEPC_ARCH]) - -# Define a macro for a nice error message that preserves the -# formatting. Use like: -# -# SLEPC_ERROR_MESSAGE -# -# with no identation - m4_define(SLEPC_ERROR_MESSAGE, - [ You may need to specify SLEPC_DIR and SLEPC_ARCH like so: - --with-slepc SLEPC_DIR=\$SLEPC_DIR SLEPC_ARCH=\$SLEPC_ARCH - Also see the help online: - http://bout-dev.readthedocs.io/en/latest/user_docs/advanced_install.html#slepc - ]) - -# Slepc changed the location of the conf directory in 3.5, so we -# need to check both locations - AC_CHECK_FILE($SLEPC_DIR/$SLEPC_ARCH/conf, [ - SLEPC_CONFDIR=${SLEPC_DIR}/conf - ], [ - AC_CHECK_FILE($SLEPC_DIR/$SLEPC_ARCH/lib/slepc/conf, [ - SLEPC_CONFDIR=${SLEPC_DIR}/lib/slepc/conf - ], [ - AC_MSG_ERROR([--with-slepc was specified but could not find Slepc distribution. -SLEPC_ERROR_MESSAGE]) - ]) - ]) - -# We've found an installation, need to check we can use it. First we -# need to be able to check the version number, for which we need -# slepcverion.h - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I$SLEPC_DIR/include" - AC_CHECK_HEADER([slepcversion.h], - [FOUND_SLEPC_HEADER=yes], - [FOUND_SLEPC_HEADER=no] - ) - -# This is a terrible hack for some Linux distributions (Fedora) that -# install Slepc in a non-supported fashion. This is really the fault -# of Slepc for their weird method of installation - AS_IF([test $FOUND_SLEPC_HEADER = no], [ - AC_CHECK_FILE([${SLEPC_CONFDIR}/slepc_variables], [], [ - AC_MSG_ERROR([Unable to find either slepcversion.h or slepc_variables -SLEPC_ERROR_MESSAGE]) - ]) - -# This relies on the assumption that SLEPC_ARCH is empty - SLEPC_CC_INCLUDES=$(grep ^SLEPC_CC_INCLUDES ${SLEPC_CONFDIR}/slepc_variables | cut -d= -f 2-) - - AC_MSG_NOTICE([Looking for slepcverion.h using $SLEPC_CC_INCLUDES from ${SLEPC_CONFDIR}/slepc_variables]) - - # This is the cache variable set by the previous call to - # AC_CHECK_HEADER. We need to unset it so we can call the macro - # again, but now with different CPPFLAGS - AS_UNSET([ac_cv_header_slepcversion_h]) - - CPPFLAGS="$CPPFLAGS $SLEPC_CC_INCLUDES" - AC_CHECK_HEADER([slepcversion.h], [], [ - AC_MSG_ERROR([Couldn't find or include slepcversion.h. -SLEPC_ERROR_MESSAGE]) - ]) - ], []) - -# Now we have the header we want, we can check the version number - AC_MSG_CHECKING([Slepc is at least 3.4.0]) - AC_EGREP_CPP([yes], [ - #include - #if SLEPC_VERSION_GE(3, 4, 0) - yes - #endif - ], [SLEPC_VERSION_OK="yes"], - [SLEPC_VERSION_OK="no"]) - AC_MSG_RESULT([$SLEPC_VERSION_OK]) - CPPFLAGS="$save_CPPFLAGS" - - AS_IF([test $SLEPC_VERSION_OK = no], [ - AC_MSG_ERROR([Slepc version must be at least 3.4.0]) - ]) - -# Check if Slepc was compiled with SUNDIALS - save_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS -I$SLEPC_DIR/$SLEPC_ARCH/include" - - # Set the line to be included in the make.conf file - SLEPC_MAKE_INCLUDE="include ${SLEPC_CONFDIR}/slepc_variables" - - BOUT_HAS_SLEPC="yes" - - EXTRA_INCS="$EXTRA_INCS \$(SLEPC_INCLUDE)" - EXTRA_LIBS="$EXTRA_LIBS \$(SLEPC_LIB)" - -], [ - SLEPC_MAKE_INCLUDE= - BOUT_HAS_SLEPC="no" -]) - -############################################################# -# Solver choice: SUNDIALS' IDA, SUNDIALS' CVODE, PVODE -############################################################# - -BOUT_HAS_SUNDIALS=no -AS_IF([test "x$with_sundials" != "x" && test "x$with_sundials" != "xno"], [ - - # Now follows a few different checks for the version of SUNDIALS. - # We need the sundials_config.h header, which comes with all the - # versions we care about - - # If we've been given a path, look in there first - AS_IF([test "x$with_sundials" != "xyes"], [ - AC_CHECK_FILE([$with_sundials/include/sundials/sundials_config.h], - [SUNDIALS_INC=$with_sundials/include], [SUNDIALS_INC=""]) - ]) - - # If we've got one, add the include dir to the preprocessor flags - save_CPPFLAGS=$CPPFLAGS - AS_IF([test "x$SUNDIALS_INC" != "x"], [CPPFLAGS="-I$SUNDIALS_INC"]) - - AC_MSG_CHECKING([for SUNDIALS config header]) - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([ - #include "sundials/sundials_config.h" - ], [])], - [AC_MSG_RESULT([yes])], - [AC_MSG_RESULT([no]) - AC_MSG_FAILURE([*** Could not determine SUNDIALS version])]) - - AC_MSG_CHECKING([for SUNDIALS minor version]) - AC_EGREP_CPP([^ *\"? *[12]\.[0-5]\.], [ - #include "sundials/sundials_config.h" - #ifdef SUNDIALS_PACKAGE_VERSION - SUNDIALS_PACKAGE_VERSION - #endif - ], [sundials_minor_ver="too low"], [sundials_minor_ver=ok]) - AC_MSG_RESULT([$sundials_minor_ver]) - - CPPFLAGS=$save_CPPFLAGS - - AS_IF([test "$sundials_minor_ver" = "too low"], [ - AC_MSG_FAILURE([*** Unsupported SUNDIALS version: Requires at least 2.6]) - ]) - - # Set both IDA and CVODE if not set already - AS_IF([test "x$with_ida" = "x"], [ - with_ida=$with_sundials - ]) - - AS_IF([test "x$with_cvode" = "x"], [ - with_cvode=$with_sundials - ]) - - AS_IF([test "x$with_arkode" = "x"], [ - with_arkode=$with_sundials - ]) - BOUT_HAS_SUNDIALS=yes -]) - -AS_IF([test "x$with_ida" != "x" && test "x$with_ida" != "xno"], [ - BOUT_FIND_SUNDIALS_MODULE([ida], [ - #include - #include - extern void foo(N_Vector); - ], [IDACreate();]) -]) - -AS_IF([test "x$with_cvode" != "x" && test "x$with_cvode" != "xno"], [ - BOUT_FIND_SUNDIALS_MODULE([cvode], [ - #include - #include - extern void foo(N_Vector); - ], [ - #if SUNDIALS_VERSION_MAJOR >= 4 - CVodeCreate(0); - #else - CVodeCreate(0, 0); - #endif - ]) -]) - -AS_IF([test "x$with_arkode" != "x" && test "x$with_arkode" != "xno"], [ - BOUT_FIND_SUNDIALS_MODULE([arkode], [ - #include - #if SUNDIALS_VERSION_MAJOR >= 4 - #include - #else - #include - #endif - extern void foo(N_Vector); - ], [ - #if SUNDIALS_VERSION_MAJOR >= 4 - ARKStepCreate(0, 0, 0, 0); - #else - ARKodeCreate(); - #endif - ]) -]) - -############################################################# -# HYPRE -############################################################# - -BOUT_HAS_HYPRE="no" -AS_IF([test "$with_hypre" != "no"], [ - BOUT_ADDPATH_CHECK_HEADER(HYPRE.h, - BOUT_ADDPATH_CHECK_LIB(HYPRE, HYPRE_IJVectorCreate, - [ - BOUT_HAS_HYPRE="yes" - ], - AC_MSG_ERROR([HYPRE requested but not found]), - $with_hypre), - AC_MSG_ERROR([HYPRE requested but not found]), - $with_hypre - ) -]) - -############################################################# -# Scorep setup -############################################################# - -BOUT_HAS_SCOREP="no" -AS_IF([test "$with_scorep" != "no"], [ - - AS_IF([test "$with_scorep" != "yes"], [ - AC_MSG_NOTICE([Searching for Scorep executable in $with_scorep]) - AC_PATH_PROG([SCOREPPATH], [scorep], [], [$with_scorep]) - ], [ - AC_MSG_NOTICE([Searching for Scorep executable]) - AC_PATH_PROG([SCOREPPATH], [scorep], []) - ]) - - AS_IF([test "$SCOREPPATH" = ""], [ - AC_MSG_FAILURE([*** Scorep requested, but executable not found. -Please supply the path using --with-scorep=/path/to/scorep]) - ],[ - CXX="$SCOREPPATH --user --nocompiler $CXX" - BOUT_HAS_SCOREP="yes" - AC_MSG_NOTICE([Scorep support enabled]) - ]) - - ],[ - AC_MSG_NOTICE([Scorep support disabled]) -]) - -############################################################# -# Check for mpark.variant -############################################################# - -AS_IF([test ".$with_system_mpark" = "no"], [ - SYSTEM_HAS_MPARK=no -], [ - AC_MSG_CHECKING([for mpark.variant]) - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([ - #include "mpark/variant.hpp" - ], [])], - [AC_MSG_RESULT([yes]) - SYSTEM_HAS_MPARK=yes], - [AC_MSG_RESULT([no]) - SYSTEM_HAS_MPARK=no - AS_IF([test "$with_system_mpark" = "yes"], [ - AC_MSG_FAILURE([*** System mpark.variant not found - but requested to use]) - ])]) -]) - -AS_IF([test "$SYSTEM_HAS_MPARK" = "yes"], [ - MPARK_VARIANT_INCLUDE_PATH= - MPARK_INCLUDE= - OWN_MPARK= -], [ - AS_IF([test -d externalpackages/mpark.variant/include], [], - [ AS_IF([test -d .git && which git], [ - make -f makefile.submodules mpark_submodule || \ - AC_MSG_FAILURE([*** Could not download mpark.variant]) - ], [ - AC_MSG_FAILURE([mpark.variant not found. Please install mpark.variant or use the official releases.]) - ]) - ]) - - MPARK_VARIANT_INCLUDE_PATH="$PWD/externalpackages/mpark.variant/include" - MPARK_INCLUDE="-I$MPARK_VARIANT_INCLUDE_PATH" - OWN_MPARK=yes -]) - -############################################################# -# Check for libuuid -############################################################# - -AS_IF([test ".$with_system_uuid" = "no"], [ - BOUT_HAS_UUID_SYSTEM_GENERATOR=no -], [ - BOUT_ADDPATH_CHECK_HEADER(uuid/uuid.h, - BOUT_ADDPATH_CHECK_LIB(uuid, uuid_generate, - BOUT_HAS_UUID_SYSTEM_GENERATOR=yes, - BOUT_HAS_UUID_SYSTEM_GENERATOR=no, - [$with_system_uuid]), - BOUT_HAS_UUID_SYSTEM_GENERATOR=no, - [$with_system_uuid]) - AS_IF([test "$with_system_uuid" = "yes"], [ - AC_MSG_FAILURE([*** System UUID generator not found, but explicitly requested]) - ]) -]) - -############################################################# -# Download + Build PVODE '98 -############################################################# - -AS_MKDIR_P(externalpackages) -AS_MKDIR_P(lib) -AS_MKDIR_P(include) - -BOUT_HAS_PVODE="no" -AS_IF([test "$with_pvode" != "no"], [ - AS_IF([test "$enable_pvode_openmp" != "no" ], [ - AS_IF([test "$enable_openmp" != "no" ], [ - PVODE_FLAGS="$CXXFLAGS $OPENMP_CXXFLAGS" - AC_MSG_NOTICE([PVODE being built with OpenMP support]) - ], [ - AC_MSG_ERROR([Cannot enable openmp in PVODE as configuring with OpenMP disabled]) - ]) - ], [ - PVODE_FLAGS="$CXXFLAGS" - AC_MSG_NOTICE([PVODE being built without OpenMP support]) - ]) - # Clean PVODE - CXX="$CXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE clean -C externalpackages/PVODE/precon/ >> config-build.log 2>&1 - CXX="$CXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE clean -C externalpackages/PVODE/source/ >> config-build.log 2>&1 - - AC_MSG_NOTICE([Building PVODE]) - echo "* Building PVODE" >> config-build.log - echo "*************************************************************" >> config-build.log - - CXX="$CXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE -C externalpackages/PVODE/precon/ >> config-build.log 2>&1 - CXX="$CXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE -C externalpackages/PVODE/source/ >> config-build.log 2>&1 - - AS_IF([test -f externalpackages/PVODE/lib/libpvode.a && test -f externalpackages/PVODE/lib/libpvpre.a], [ - AC_MSG_NOTICE([Successfully built PVODE]) - AC_MSG_NOTICE([Installing PVODE into BOUT++ sourcetree]) - - echo "*************************************************************" >> config-build.log - echo "* Successfully built PVODE" >> config-build.log - echo "*************************************************************" >> config-build.log - echo "* Installing PVODE into BOUT++ sourcetree" >> config-build.log - echo "*************************************************************" >> config-build.log - ], [ - AC_MSG_ERROR(Could not build PVODE. See config-build.log for errors) - ]) - - # Set the correct libraries and copy them to bout - AS_MKDIR_P(include/pvode) - cp -r externalpackages/PVODE/include/pvode include - cp externalpackages/PVODE/lib/*.a lib/ - EXTRA_LIBS="$EXTRA_LIBS -L\$(BOUT_LIB_PATH) -lpvode -lpvpre" - BOUT_HAS_PVODE="yes" -]) - -############################################################# -# Localisation (i18n) with gettext -############################################################# - -BOUT_HAS_GETTEXT="no" -# Use macro to test if Natural Language Support (gettext) is available. -# If available sets: -# - USE_NLS to "yes" -# - LIBINTL to the linker options -# - Modifies CPPFLAGS if needed -AM_GNU_GETTEXT([external]) -AS_IF([test "$USE_NLS" = "yes"], [ - AC_MSG_NOTICE([Enabling language support with gettext]) - # Turn the .po files into .mo files - $MAKE -C locale | tee -a config-build.log 2>&1 - - # Note: BOUT_LOCALE_PATH is defined in make.config, and may be changed by `make install`. - CXXFLAGS="$CXXFLAGS -DBOUT_LOCALE_PATH=\$(BOUT_LOCALE_PATH)" - - EXTRA_LIBS="$EXTRA_LIBS $LIBINTL" - - # Set variable substituted into bout-config - BOUT_HAS_GETTEXT="yes" -],[ - AC_MSG_NOTICE([Language support with gettext not available]) -]) - -############################################################# -# Sort out fmt -############################################################# - -dnl If in a git repo, get submodule, unless BOUT_DONT_UPDATE_GIT_SUBMODULE is set -AC_CHECK_FILE([.git], [ - AS_IF([test "x$BOUT_DONT_UPDATE_GIT_SUBMODULE" == "x"], [ - git submodule update --init externalpackages/fmt - ]) -]) - -dnl Copy the one file we need to somewhere else -AC_CONFIG_LINKS(src/fmt/format.cxx:externalpackages/fmt/src/format.cc) - -############################################################# -# Check environment -############################################################# - -AS_IF([test "$CXXINCLUDE" != ""], [ - AC_MSG_NOTICE([================================================]) - AC_MSG_NOTICE([ WARNING: CXXINCLUDE environment variable set to:]) - AC_MSG_NOTICE([$CXXINCLUDE]) - AC_MSG_NOTICE([ => This will be added to compile commands]) - AC_MSG_NOTICE([ If this is not intended, then run]) - AC_MSG_NOTICE([ export CXXINCLUDE='']) - AC_MSG_NOTICE([ before making BOUT++]) - AC_MSG_NOTICE([================================================]) -]) - -############################################################# -# Gather configuration info for bout-config -############################################################# - -EXTRA_INCS="${EXTRA_INCS} ${CPPFLAGS}" - -PREFIX=$PWD -IDLCONFIGPATH=$PWD/tools/idllib -PYTHONCONFIGPATH=$PWD/tools/pylib - -BOUT_HAS_IDA="yes" -if test "$IDALIBS" = "" -then - BOUT_HAS_IDA="no" -fi - -BOUT_HAS_CVODE="yes" -if test "$CVODELIBS" = "" -then - BOUT_HAS_CVODE="no" -fi - -BOUT_HAS_ARKODE="yes" -if test "$ARKODELIBS" = "" -then - BOUT_HAS_ARKODE="no" -fi - -BOUT_HAS_PNETCDF="yes" -if test "$PNCPATH" = "" -then - BOUT_HAS_PNETCDF="no" -fi - -# Only make.config is altered by configure -AC_CONFIG_FILES([make.config]) -AC_OUTPUT - -############################################################# -# Use a dummy Makefile to get the cflags and ldflags -# -# This is to capture flags from external libraries such -# as PETSc -############################################################# - -CONFIG_CFLAGS=`$MAKE cflags -f output.make` -CONFIG_LDFLAGS=`$MAKE ldflags -f output.make` - -############################################################# -# Defines which are supported by CMake build but not autoconf - -BOUT_HAS_CUDA="no" -BOUT_HAS_RAJA="no" -BOUT_HAS_UMPIRE="no" -BOUT_HAS_CALIPER="no" - -BOUT_DEFINE_SUBST(BOUT_HAS_CUDA, [Enable CUDA]) -BOUT_DEFINE_SUBST(BOUT_HAS_RAJA, [RAJA support]) -BOUT_DEFINE_SUBST(BOUT_HAS_UMPIRE, [Umpire support]) -BOUT_DEFINE_SUBST(BOUT_HAS_CALIPER, [Caliper support]) - -############################################################# -# Write configuration to bout-config -############################################################# - -AC_SUBST(CONFIG_CFLAGS) -AC_SUBST(CONFIG_LDFLAGS) - -# Set path to lib and include here. -# If make install is run then that replaces these paths -BOUT_LIB_PATH=$PWD/lib -BOUT_INCLUDE_PATH=$PWD/include -FMT_INCLUDE_PATH=$PWD/externalpackages/fmt/include -AC_SUBST(BOUT_LIB_PATH) -AC_SUBST(BOUT_INCLUDE_PATH) -AC_SUBST(FMT_INCLUDE_PATH) -AC_SUBST(MPARK_VARIANT_INCLUDE_PATH) -AC_SUBST(MPARK_INCLUDE) -AC_SUBST(OWN_MPARK) - -AC_SUBST(PREFIX) -AC_SUBST(IDLCONFIGPATH) -AC_SUBST(PYTHONCONFIGPATH) -AC_SUBST(LIB_TO_BUILD) -AC_SUBST(STATIC_EXTRA) -AC_SUBST(SHARED_EXTRA) - -AC_SUBST(BOUT_VERSION) -AC_SUBST(BOUT_VERSION_MAJOR) -AC_SUBST(BOUT_VERSION_MINOR) -AC_SUBST(BOUT_VERSION_PATCH) -AC_SUBST(BOUT_VERSION_TAG) -AC_SUBST(BOUT_REVISION) - -AC_SUBST(BOUT_CHECK_LEVEL) -AC_DEFINE_UNQUOTED(BOUT_CHECK_LEVEL, [$BOUT_CHECK_LEVEL], [Runtime error checking level]) - -AC_SUBST(BOUT_OPENMP_SCHEDULE) -AC_DEFINE_UNQUOTED(BOUT_OPENMP_SCHEDULE, [$BOUT_OPENMP_SCHEDULE], [OpenMP schedule]) - -BOUT_DEFINE_SUBST(BOUT_HAS_ARKODE, [ARKODE support]) -BOUT_DEFINE_SUBST(BOUT_HAS_CVODE, [CVODE support]) -BOUT_DEFINE_SUBST(BOUT_HAS_FFTW, [FFTW support]) -BOUT_DEFINE_SUBST(BOUT_HAS_GETTEXT, [NLS support]) -BOUT_DEFINE_SUBST(BOUT_HAS_IDA, [IDA support]) -BOUT_DEFINE_SUBST(BOUT_HAS_LAPACK, [LAPACK support]) -BOUT_DEFINE_SUBST(BOUT_HAS_NETCDF, [NETCDF support]) -BOUT_DEFINE_SUBST(BOUT_HAS_LEGACY_NETCDF, [NETCDF support]) -BOUT_DEFINE_SUBST(BOUT_HAS_PETSC, [PETSc support]) -BOUT_DEFINE_SUBST(BOUT_HAS_HYPRE, [Hypre support]) -BOUT_DEFINE_SUBST(BOUT_HAS_PNETCDF, [PNETCDF support]) -BOUT_DEFINE_SUBST(BOUT_HAS_PRETTY_FUNCTION, [Compiler PRETTYFUNCTION support]) -BOUT_DEFINE_SUBST(BOUT_HAS_PVODE, [PVODE support]) -BOUT_DEFINE_SUBST(BOUT_HAS_SCOREP, [Score-P support]) -BOUT_DEFINE_SUBST(BOUT_HAS_SLEPC, [SLEPc support]) -BOUT_DEFINE_SUBST(BOUT_HAS_SUNDIALS, [SUNDIALS support]) -BOUT_DEFINE_SUBST(BOUT_HAS_UUID_SYSTEM_GENERATOR, [Use libuuid for UUID generation]) -BOUT_DEFINE_SUBST(BOUT_USE_BACKTRACE, [Enable backtrace in exceptions]) -BOUT_DEFINE_SUBST(BOUT_USE_COLOR, [Enable color logs option]) -BOUT_DEFINE_SUBST(BOUT_USE_OUTPUT_DEBUG, [Enabled extra debug output]) -BOUT_DEFINE_SUBST(BOUT_USE_OPENMP, [Enable OpenMP]) -BOUT_DEFINE_SUBST(BOUT_USE_SIGFPE, [Enable floating point exceptions]) -BOUT_DEFINE_SUBST(BOUT_USE_SIGNAL, [Enable signal handlers]) -BOUT_DEFINE_SUBST(BOUT_USE_TRACK, [Enable field name tracking]) -BOUT_DEFINE_SUBST(BOUT_USE_MSGSTACK, [Enable MsgStack for traces]) -AC_DEFINE_UNQUOTED([BOUT_METRIC_TYPE], $BOUT_METRIC_TYPE, [Type of the metric fields]) -BOUT_METRIC_3D=$(test $BOUT_METRIC_TYPE != 3D ; echo $?) -AC_DEFINE_UNQUOTED([BOUT_USE_METRIC_3D], $BOUT_METRIC_3D, [Is the metric field 3D]) -AC_SUBST(BOUT_METRIC_TYPE) - -AC_SUBST(PETSC_HAS_SUNDIALS) -AC_SUBST(PETSC_MAKE_INCLUDE) -AC_SUBST(PETSC_DIR) -AC_SUBST(PETSC_ARCH) -AC_SUBST(SLEPC_MAKE_INCLUDE) -AC_SUBST(SLEPC_DIR) -AC_SUBST(SLEPC_ARCH) - - -AC_CONFIG_HEADERS([include/bout/build_defines.hxx:autoconf_build_defines.hxx.in]) -AC_CONFIG_FILES([include/bout/version.hxx]) -AC_CONFIG_FILES([include/bout/revision.hxx]) -AC_CONFIG_FILES([bin/bout-config]) -AC_CONFIG_FILES([src/makefile]) -AC_CONFIG_FILES([tools/pylib/boutconfig/__init__.py]) -AC_OUTPUT -chmod a+x bin/bout-config - -############################################################# -# Print configuration info -############################################################# - -AC_MSG_NOTICE([-------------------------]) -AC_MSG_NOTICE([ Configuration summary ]) -AC_MSG_NOTICE([-------------------------]) - -AC_MSG_NOTICE([ PETSc support : $BOUT_HAS_PETSC (has SUNDIALS: $PETSC_HAS_SUNDIALS)]) -AC_MSG_NOTICE([ SLEPc support : $BOUT_HAS_SLEPC]) -AC_MSG_NOTICE([ IDA support : $BOUT_HAS_IDA]) -AC_MSG_NOTICE([ CVODE support : $BOUT_HAS_CVODE]) -AC_MSG_NOTICE([ ARKODE support : $BOUT_HAS_ARKODE]) -AC_MSG_NOTICE([ FFTW support : $BOUT_HAS_FFTW]) -AC_MSG_NOTICE([ NetCDF support : $BOUT_HAS_NETCDF (legacy: $BOUT_HAS_LEGACY_NETCDF)]) -AC_MSG_NOTICE([ Parallel-NetCDF support : $BOUT_HAS_PNETCDF]) -AC_MSG_NOTICE([ Lapack support : $BOUT_HAS_LAPACK]) -AC_MSG_NOTICE([ Scorep support : $BOUT_HAS_SCOREP]) -AC_MSG_NOTICE([ OpenMP support : $BOUT_USE_OPENMP (schedule: $OPENMP_SCHEDULE)]) -AC_MSG_NOTICE([ Natural language support: $BOUT_HAS_GETTEXT (path: $localedir)]) -AC_MSG_NOTICE([ HYPRE support : $BOUT_HAS_HYPRE]) -AC_MSG_NOTICE([ System UUID generator : $BOUT_HAS_UUID_SYSTEM_GENERATOR]) -AC_MSG_NOTICE([]) -AC_MSG_NOTICE([ Enable backtrace : $BOUT_USE_BACKTRACE]) -AC_MSG_NOTICE([ Enable color logs : $BOUT_USE_COLOR]) -AC_MSG_NOTICE([ Enable more debug output: $BOUT_USE_OUTPUT_DEBUG]) -AC_MSG_NOTICE([ Enable OpenMP : $BOUT_USE_OPENMP]) -AC_MSG_NOTICE([ Enable FP exceptions : $BOUT_USE_SIGFPE]) -AC_MSG_NOTICE([ Enable signal handlers : $BOUT_USE_SIGNAL]) -AC_MSG_NOTICE([ Enable field names : $BOUT_USE_TRACK]) -AC_MSG_NOTICE([ Metric type : $BOUT_METRIC_TYPE]) - -AC_MSG_NOTICE([]) -AC_MSG_NOTICE([-------------------------------]) -AC_MSG_NOTICE([ Data analysis configuration ]) -AC_MSG_NOTICE([-------------------------------]) -AC_MSG_NOTICE([]) -AC_MSG_NOTICE([=== IDL ===]) -AC_MSG_NOTICE([]) -AC_MSG_NOTICE([Make sure that the tools/idllib directory is in your IDL_PATH]) -AC_MSG_NOTICE([e.g. by adding to your ~/.bashrc file]) -AC_MSG_NOTICE([]) -AC_MSG_NOTICE([ export IDL_PATH=+$PWD/tools/idllib:'':\$IDL_PATH]) -AC_MSG_NOTICE([]) -AC_MSG_NOTICE([=== Python ===]) -AC_MSG_NOTICE([]) -AC_MSG_NOTICE([Make sure that the tools/pylib directory is in your PYTHONPATH]) -AC_MSG_NOTICE([e.g. by adding to your ~/.bashrc file]) -AC_MSG_NOTICE([]) -AC_MSG_NOTICE([ export PYTHONPATH=$PWD/tools/pylib/:\$PYTHONPATH]) -AC_MSG_NOTICE([]) -AC_MSG_NOTICE([*** Now run '$MAKE' to compile BOUT++ ***]) -AC_MSG_NOTICE([]) -AC_MSG_WARN([./configure is deprecated and will be removed in a future version, please use CMake instead]) diff --git a/examples/2Dturbulence_multigrid/makefile b/examples/2Dturbulence_multigrid/makefile deleted file mode 100644 index f67cb0d1ba..0000000000 --- a/examples/2Dturbulence_multigrid/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../ - -SOURCEC = esel.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/6field-simple/makefile b/examples/6field-simple/makefile deleted file mode 100644 index 6f70c9d751..0000000000 --- a/examples/6field-simple/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../ - -SOURCEC = elm_6f.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 3849d34852..022b16e248 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -11,6 +11,7 @@ add_subdirectory(backtrace) add_subdirectory(blob2d) add_subdirectory(blob2d-outerloop) add_subdirectory(blob2d-laplacexz) +add_subdirectory(boutpp) add_subdirectory(boundary-conditions/advection) add_subdirectory(conducting-wall-mode) add_subdirectory(conduction) diff --git a/examples/IMEX/advection-diffusion/makefile b/examples/IMEX/advection-diffusion/makefile deleted file mode 100644 index 588242e834..0000000000 --- a/examples/IMEX/advection-diffusion/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = imex.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/IMEX/advection-reaction/makefile b/examples/IMEX/advection-reaction/makefile deleted file mode 100644 index 689fd0c614..0000000000 --- a/examples/IMEX/advection-reaction/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = split_operator.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/IMEX/diffusion-nl/makefile b/examples/IMEX/diffusion-nl/makefile deleted file mode 100644 index 8dcd38cc0b..0000000000 --- a/examples/IMEX/diffusion-nl/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = diffusion-nl.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/IMEX/drift-wave-constraint/makefile b/examples/IMEX/drift-wave-constraint/makefile deleted file mode 100644 index fdf3abccc9..0000000000 --- a/examples/IMEX/drift-wave-constraint/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = test-drift.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/IMEX/drift-wave/makefile b/examples/IMEX/drift-wave/makefile deleted file mode 100644 index fdf3abccc9..0000000000 --- a/examples/IMEX/drift-wave/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = test-drift.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/advdiff/makefile b/examples/advdiff/makefile deleted file mode 100644 index 15bffe5c29..0000000000 --- a/examples/advdiff/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = advdiff.cxx - -include $(BOUT_TOP)/make.config \ No newline at end of file diff --git a/examples/advdiff2/makefile b/examples/advdiff2/makefile deleted file mode 100644 index e17c2c3c7a..0000000000 --- a/examples/advdiff2/makefile +++ /dev/null @@ -1,7 +0,0 @@ -BOUT_TOP ?= ../.. - -SOURCEC = init.cxx rhs.cxx - -TARGET = advdiff - -include $(BOUT_TOP)/make.config diff --git a/examples/backtrace/makefile b/examples/backtrace/makefile deleted file mode 100644 index cb5c651884..0000000000 --- a/examples/backtrace/makefile +++ /dev/null @@ -1,11 +0,0 @@ -BOUT_TOP ?= ../.. - -TARGET=backtrace - -SOURCEC = $(TARGET).cxx - -include $(BOUT_TOP)/make.config - -$(TARGET).o: $(TARGET).cxx - @echo " Compiling " $< - @$(CXX) $(BOUT_INCLUDE) $(BOUT_FLAGS) -c $< -g -o $@ diff --git a/examples/blob2d-laplacexz/makefile b/examples/blob2d-laplacexz/makefile deleted file mode 100644 index ca2f949a73..0000000000 --- a/examples/blob2d-laplacexz/makefile +++ /dev/null @@ -1,6 +0,0 @@ -BOUT_TOP ?= ../.. - -SOURCEC = blob2d.cxx - -include $(BOUT_TOP)/make.config - diff --git a/examples/blob2d-outerloop/makefile b/examples/blob2d-outerloop/makefile deleted file mode 100644 index 1ab6de5387..0000000000 --- a/examples/blob2d-outerloop/makefile +++ /dev/null @@ -1,6 +0,0 @@ -BOUT_TOP = ../.. - -SOURCEC = blob2d.cxx - -include $(BOUT_TOP)/make.config - diff --git a/examples/blob2d/blob2d.cxx b/examples/blob2d/blob2d.cxx index f41f857d46..7007bbeb77 100644 --- a/examples/blob2d/blob2d.cxx +++ b/examples/blob2d/blob2d.cxx @@ -25,7 +25,6 @@ class Blob2D : public PhysicsModel { BoutReal rho_s; ///< Bohm gyro radius BoutReal Omega_i; ///< Ion cyclotron frequency BoutReal c_s; ///< Bohm sound speed - BoutReal n0; ///< Reference density // Constants to calculate the parameters BoutReal Te0; ///< Isothermal temperature [eV] @@ -61,7 +60,6 @@ class Blob2D : public PhysicsModel { m_i = options["m_i"].withDefault(2 * 1.667e-27); m_e = options["m_e"].withDefault(9.11e-31); - n0 = options["n0"].doc("Background density in cubic m").withDefault(1e19); D_vort = options["D_vort"].doc("Viscous diffusion coefficient").withDefault(0.0); D_n = options["D_n"].doc("Density diffusion coefficient").withDefault(0.0); diff --git a/examples/blob2d/delta_0.25/BOUT.inp b/examples/blob2d/delta_0.25/BOUT.inp index 58d1e36741..841fcaf235 100644 --- a/examples/blob2d/delta_0.25/BOUT.inp +++ b/examples/blob2d/delta_0.25/BOUT.inp @@ -87,8 +87,6 @@ flags = 49152 # set_rhs i.e. identity matrix in boundaries Te0 = 5 # Electron Temperature (eV) -n0 = 2e+18 # Background plasma density (m^-3) - compressible = false # Compressibility? boussinesq = true # Boussinesq approximation (no perturbed n in vorticity) diff --git a/examples/blob2d/delta_1/BOUT.inp b/examples/blob2d/delta_1/BOUT.inp index 417911271d..39213ddd36 100644 --- a/examples/blob2d/delta_1/BOUT.inp +++ b/examples/blob2d/delta_1/BOUT.inp @@ -87,8 +87,6 @@ flags = 49152 # set_rhs i.e. identity matrix in boundaries Te0 = 5 # Electron Temperature (eV) -n0 = 2e+18 # Background plasma density (m^-3) - compressible = false # Compressibility? boussinesq = true # Boussinesq approximation (no perturbed n in vorticity) diff --git a/examples/blob2d/delta_10/BOUT.inp b/examples/blob2d/delta_10/BOUT.inp index 353c28c3b2..f4507b871b 100644 --- a/examples/blob2d/delta_10/BOUT.inp +++ b/examples/blob2d/delta_10/BOUT.inp @@ -87,8 +87,6 @@ flags = 49152 # set_rhs i.e. identity matrix in boundaries Te0 = 5 # Electron Temperature (eV) -n0 = 2e+18 # Background plasma density (m^-3) - compressible = false # Compressibility? boussinesq = true # Boussinesq approximation (no perturbed n in vorticity) diff --git a/examples/blob2d/makefile b/examples/blob2d/makefile deleted file mode 100644 index ca2f949a73..0000000000 --- a/examples/blob2d/makefile +++ /dev/null @@ -1,6 +0,0 @@ -BOUT_TOP ?= ../.. - -SOURCEC = blob2d.cxx - -include $(BOUT_TOP)/make.config - diff --git a/examples/boundary-conditions/advection/makefile b/examples/boundary-conditions/advection/makefile deleted file mode 100644 index 962ca894c2..0000000000 --- a/examples/boundary-conditions/advection/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = advection.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/boutpp/CMakeLists.txt b/examples/boutpp/CMakeLists.txt new file mode 100644 index 0000000000..e46a7ae990 --- /dev/null +++ b/examples/boutpp/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.13) + +if (NOT TARGET bout++::bout++) + find_package(bout++ REQUIRED) +endif() + +bout_copy_file(runexample) +bout_copy_file(blob2d.py) +bout_copy_file(simulation.py) +bout_copy_file(data/BOUT.inp) diff --git a/examples/boutpp/blob2d.py b/examples/boutpp/blob2d.py index d5f370a454..4dc8ea60ac 100755 --- a/examples/boutpp/blob2d.py +++ b/examples/boutpp/blob2d.py @@ -24,7 +24,7 @@ def init(self, restart): self.phiSolver = bc.Laplacian() - options = bc.Options("model") + options = bc.Options.root("model") # Temperature in eV Te0 = options.get("Te0", 30) e = options.get("e", 1.602e-19) @@ -70,12 +70,20 @@ def init(self, restart): # /************ Create a solver for potential ********/ + opts_boussinesq = bc.Options.root("phiBoussinesq") + opts_non_boussinesq = bc.Options.root("phiSolver") + if self.boussinesq: # BOUT.inp section "phiBoussinesq" - self.phiSolver = bc.Laplacian(bc.Options("phiBoussinesq")) + opts_used = opts_boussinesq + opts_unused = opts_non_boussinesq else: # BOUT.inp section "phiSolver" - self.phiSolver = bc.Laplacian(bc.Options("phiSolver")) + opts_used = opts_non_boussinesq + opts_unused = opts_boussinesq + + self.phiSolver = bc.Laplacian(opts_used) + opts_unused.setConditionallyUsed() # Starting guess for first solve (if iterative) self.phi = bc.create3D("0") @@ -165,8 +173,8 @@ def ensure_blob(): # settings used by the core code -NOUT = 50 # number of time-steps -TIMESTEP = 50 # time between outputs [1/wci] +nout = 50 # number of time-steps +timestep = 50 # time between outputs [1/wci] MXG = 2 # Number of X guard cells @@ -198,8 +206,8 @@ def ensure_blob(): [mesh:ddz] -first = FFT -second = FFT +first = C2 +second = C2 upwind = W3 ################################################### @@ -207,8 +215,8 @@ def ensure_blob(): [solver] -ATOL = 1.0e-10 # absolute tolerance -RTOL = 1.0e-5 # relative tolerance +atol = 1e-10 # absolute tolerance +rtol = 1e-05 # relative tolerance mxstep = 10000 # Maximum internal steps per output ################################################### @@ -221,22 +229,20 @@ def ensure_blob(): fourth_order = true # 4th order or 2nd order -flags = 0 # inversion flags for phi - # 0 = Zero value - # 10 = Zero gradient AC inner & outer - # 15 = Zero gradient AC and DC - # 768 = Zero laplace inner & outer +# 0 = Zero value +# 10 = Zero gradient AC inner & outer +# 15 = Zero gradient AC and DC +# 768 = Zero laplace inner & outer [phiSolver:precon] # Preconditioner (if pctype=user) -filter = 0. # Must not filter solution -flags = 49152 # set_rhs i.e. identity matrix in boundaries +filter = 0.0 # Must not filter solution +flags = 49152 # set_rhs i.e. identity matrix in boundaries ################################################### # Electrostatic potential solver (Boussinesq) [phiBoussinesq] # By default type is tri (serial) or spt (parallel) -flags = 0 ################################################## # general settings for the model @@ -245,14 +251,12 @@ def ensure_blob(): Te0 = 5 # Electron Temperature (eV) -n0 = 2e18 # Background plasma density (m^-3) - compressible = false # Compressibility? boussinesq = true # Boussinesq approximation (no perturbed n in vorticity) -D_vort = 1e-6 # Viscosity -D_n = 1e-6 # Diffusion +D_vort = 1e-06 # Viscosity +D_n = 1e-06 # Diffusion R_c = 1.5 # Radius of curvature (m) @@ -261,7 +265,7 @@ def ensure_blob(): # These can be overridden for individual variables in # a section of that name. -[All] +[all] scale = 0.0 # default size of initial perturbations bndry_all = neumann # Zero-gradient on all boundaries @@ -278,9 +282,8 @@ def ensure_blob(): if __name__ == "__main__": - if "--create" in sys.argv: - sys.argv.remove("--create") - ensure_blob() + ensure_blob() + bc.init("-d blob".split(" ") + sys.argv[1:]) # Create an instance diff --git a/examples/boutpp/data/BOUT.inp b/examples/boutpp/data/BOUT.inp new file mode 100644 index 0000000000..d91707ec1b --- /dev/null +++ b/examples/boutpp/data/BOUT.inp @@ -0,0 +1,9 @@ +nout=10 +timestep=10 + +[mesh] +nx=160 +ny=1 +nz=n/n + +MYG=0 diff --git a/examples/conducting-wall-mode/makefile b/examples/conducting-wall-mode/makefile deleted file mode 100644 index e3375e06d9..0000000000 --- a/examples/conducting-wall-mode/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = cwm.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/conduction-snb/makefile b/examples/conduction-snb/makefile deleted file mode 100644 index 90ecf242d8..0000000000 --- a/examples/conduction-snb/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = conduction-snb.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/conduction/makefile b/examples/conduction/makefile deleted file mode 100644 index 26a2d2686e..0000000000 --- a/examples/conduction/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = conduction.cxx - -include $(BOUT_TOP)/make.config \ No newline at end of file diff --git a/examples/constraints/alfven-wave/makefile b/examples/constraints/alfven-wave/makefile deleted file mode 100644 index cc53facb8e..0000000000 --- a/examples/constraints/alfven-wave/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = alfven.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/constraints/laplace-dae/makefile b/examples/constraints/laplace-dae/makefile deleted file mode 100644 index 224a696106..0000000000 --- a/examples/constraints/laplace-dae/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = laplace_dae.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/dalf3/doc/makefile b/examples/dalf3/doc/makefile deleted file mode 100644 index 6812b687f9..0000000000 --- a/examples/dalf3/doc/makefile +++ /dev/null @@ -1,11 +0,0 @@ - -DOCS=dalf3.pdf - -all:$(DOCS) - -%.pdf: %.tex - latexmk -pdf $< -interaction=batchmode - -.PHONY: clean -clean: - latexmk -C diff --git a/examples/dalf3/makefile b/examples/dalf3/makefile deleted file mode 100644 index 3c9eed60c1..0000000000 --- a/examples/dalf3/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = dalf3.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/eigen-box/makefile b/examples/eigen-box/makefile deleted file mode 100644 index 53855e725b..0000000000 --- a/examples/eigen-box/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = eigen-box.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/elm-pb-outerloop/data/BOUT.inp b/examples/elm-pb-outerloop/data/BOUT.inp index d06073f838..6c9f268057 100644 --- a/examples/elm-pb-outerloop/data/BOUT.inp +++ b/examples/elm-pb-outerloop/data/BOUT.inp @@ -13,9 +13,6 @@ MZ = 16 # Number of points in Z grid = "cbm18_dens8.grid_nx68ny64.nc" # Grid file -dump_format = "nc" # Dump file format. "nc" = NetCDF, "pdb" = PDB -restart_format = "nc" # Restart file format - [mesh] staggergrids = false # Use staggered grids @@ -44,9 +41,6 @@ first = C4 # Z derivatives can be done using FFT second = C4 upwind = W3 -[output] -shiftoutput = true # Put the output into field-aligned coordinates - ################################################## # FFTs diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 691f4303f4..8e84901806 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -1576,7 +1576,17 @@ class ELMpb : public PhysicsModel { Field3D B0U = B0 * U; mesh->communicate(B0U); auto B0U_acc = FieldAccessor<>(B0U); -#endif +#else + Field3D B0phi = B0 * phi; + mesh->communicate(B0phi); + auto B0phi_acc = FieldAccessor<>(B0phi); + +#if EHALL + Field3D B0P = B0 * P; + mesh->communicate(B0 * P); + auto B0P_acc = FieldAccessor<>(B0P); +#endif // EHALL +#endif // EVOLVE_JPAR #if RELAX_J_VAC auto vac_mask_acc = FieldAccessor<>(vac_mask); @@ -1612,23 +1622,24 @@ class ELMpb : public PhysicsModel { #else // Evolve vector potential ddt(psi) - ddt(Psi_acc)[i] = - -GRAD_PARP(phi_acc) + eta_acc[i] * Jpar_acc[i] + ddt(Psi_acc)[i] = -GRAD_PARP(B0phi_acc) / B0_acc[i2d] + eta_acc[i] * Jpar_acc[i] - + EVAL_IF(EHALL, // electron parallel pressure - 0.25 * delta_i * (GRAD_PARP(P_acc) + bracket(P0_acc, Psi_acc, i))) + + EVAL_IF(EHALL, // electron parallel pressure + 0.25 * delta_i + * (GRAD_PARP(B0P_acc) / B0_acc[i2d] + + bracket(P0_acc, Psi_acc, i) * B0_acc[i2d])) - - EVAL_IF(DIAMAG_PHI0, // Equilibrium flow - bracket(phi0_acc, Psi_acc, i)) + - EVAL_IF(DIAMAG_PHI0, // Equilibrium flow + bracket(phi0_acc, Psi_acc, i) * B0_acc[i2d]) - + EVAL_IF(DIAMAG_GRAD_T, // grad_par(T_e) correction - 1.71 * dnorm * 0.5 * GRAD_PARP(P_acc) / B0_acc[i2d]) + + EVAL_IF(DIAMAG_GRAD_T, // grad_par(T_e) correction + 1.71 * dnorm * 0.5 * GRAD_PARP(P_acc) / B0_acc[i2d]) - - EVAL_IF(HYPERRESIST, // Hyper-resistivity - eta_acc[i] * hyperresist * Delp2(Jpar_acc, i)) + - EVAL_IF(HYPERRESIST, // Hyper-resistivity + eta_acc[i] * hyperresist * Delp2(Jpar_acc, i)) - - EVAL_IF(EHYPERVISCOS, // electron Hyper-viscosity - eta_acc[i] * ehyperviscos * Delp2(Jpar2_acc, i)); + - EVAL_IF(EHYPERVISCOS, // electron Hyper-viscosity + eta_acc[i] * ehyperviscos * Delp2(Jpar2_acc, i)); #endif //////////////////////////////////////////////////// diff --git a/examples/elm-pb-outerloop/makefile b/examples/elm-pb-outerloop/makefile deleted file mode 100644 index 5d9b045742..0000000000 --- a/examples/elm-pb-outerloop/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../ - -SOURCEC = elm_pb_outerloop.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/elm-pb/data/BOUT.inp b/examples/elm-pb/data/BOUT.inp index 69d8bb0976..55a4a30c06 100644 --- a/examples/elm-pb/data/BOUT.inp +++ b/examples/elm-pb/data/BOUT.inp @@ -12,21 +12,18 @@ zperiod = 15 # Fraction of a torus to simulate MZ = 16 # Number of points in Z grid = "cbm18_dens8.grid_nx68ny64.nc" # Grid file -restart_format = "nc" # Restart file format [mesh] staggergrids = false # Use staggered grids [mesh:paralleltransform] - type = shifted # Use shifted metric method ################################################## # derivative methods [mesh:ddx] - first = C4 # order of first x derivatives second = C4 # order of second x derivatives upwind = W3 # order of upwinding method W3 = Weno3 @@ -42,9 +39,6 @@ first = C4 # Z derivatives can be done using FFT second = C4 upwind = W3 -[output] -shiftoutput = true # Put the output into field-aligned coordinates - ################################################## # FFTs @@ -58,8 +52,8 @@ fft_measurement_flag = measure # If using FFTW, perform tests to determine fast [solver] # mudq, mldq, mukeep, mlkeep preconditioner options -atol = 1e-08 # absolute tolerance -rtol = 1e-05 # relative tolerance +atol = 1.0e-8 # absolute tolerance +rtol = 1.0e-5 # relative tolerance use_precon = false # Use preconditioner: User-supplied or BBD @@ -160,7 +154,7 @@ damp_t_const = 1e-2 # Damping time constant diffusion_par = -1.0 # Parallel pressure diffusion (< 0 = none) diffusion_p4 = -1e-05 # parallel hyper-viscous diffusion for pressure (< 0 = none) -diffusion_u4 = 1e-05 # parallel hyper-viscous diffusion for vorticity (< 0 = none) +diffusion_u4 = -1e-05 # parallel hyper-viscous diffusion for vorticity (< 0 = none) diffusion_a4 = -1e-05 # parallel hyper-viscous diffusion for vector potential (< 0 = none) ## heat source in pressure in watts diff --git a/examples/elm-pb/doc/makefile b/examples/elm-pb/doc/makefile deleted file mode 100644 index 66f9cd76f8..0000000000 --- a/examples/elm-pb/doc/makefile +++ /dev/null @@ -1,14 +0,0 @@ -# Makefile for the reference and user manuals - -.PHONY:all - -all: elm_pb.pdf - -%.pdf: %.tex - latexmk -pdf $(@F:.pdf=) -interaction=batchmode - -.PHONY:clean - -clean: - latexmk -C - diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index 6232c72d52..f108e58e2f 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -371,8 +371,9 @@ class ELMpb : public PhysicsModel { density = options["density"].doc("Number density [m^-3]").withDefault(1.0e19); - evolve_jpar = - options["evolve_jpar"].doc("If true, evolve J raher than Psi").withDefault(false); + evolve_jpar = options["evolve_jpar"] + .doc("If true, evolve J rather than Psi") + .withDefault(false); phi_constraint = options["phi_constraint"] .doc("Use solver constraint for phi?") .withDefault(false); @@ -1426,23 +1427,30 @@ class ELMpb : public PhysicsModel { if (sheath_boundaries) { + // Need to shift into field-aligned coordinates before applying + // parallel boundary conditions + + auto phi_fa = toFieldAligned(phi); + auto P_fa = toFieldAligned(P); + auto Jpar_fa = toFieldAligned(Jpar); + // At y = ystart (lower boundary) for (RangeIterator r = mesh->iterateBndryLowerY(); !r.isDone(); r++) { for (int jz = 0; jz < mesh->LocalNz; jz++) { // Zero-gradient potential - BoutReal phisheath = phi(r.ind, mesh->ystart, jz); + BoutReal const phisheath = phi_fa(r.ind, mesh->ystart, jz); BoutReal jsheath = -(sqrt(mi_me) / (2. * sqrt(PI))) * phisheath; // Apply boundary condition half-way between cells for (int jy = mesh->ystart - 1; jy >= 0; jy--) { // Neumann conditions - P(r.ind, jy, jz) = P(r.ind, mesh->ystart, jz); - phi(r.ind, jy, jz) = phisheath; + P_fa(r.ind, jy, jz) = P_fa(r.ind, mesh->ystart, jz); + phi_fa(r.ind, jy, jz) = phisheath; // Dirichlet condition on Jpar - Jpar(r.ind, jy, jz) = 2. * jsheath - Jpar(r.ind, mesh->ystart, jz); + Jpar_fa(r.ind, jy, jz) = 2. * jsheath - Jpar_fa(r.ind, mesh->ystart, jz); } } } @@ -1453,22 +1461,27 @@ class ELMpb : public PhysicsModel { for (int jz = 0; jz < mesh->LocalNz; jz++) { // Zero-gradient potential - BoutReal phisheath = phi(r.ind, mesh->yend, jz); + BoutReal const phisheath = phi_fa(r.ind, mesh->yend, jz); BoutReal jsheath = (sqrt(mi_me) / (2. * sqrt(PI))) * phisheath; // Apply boundary condition half-way between cells for (int jy = mesh->yend + 1; jy < mesh->LocalNy; jy++) { // Neumann conditions - P(r.ind, jy, jz) = P(r.ind, mesh->yend, jz); - phi(r.ind, jy, jz) = phisheath; + P_fa(r.ind, jy, jz) = P_fa(r.ind, mesh->yend, jz); + phi_fa(r.ind, jy, jz) = phisheath; // Dirichlet condition on Jpar // WARNING: this is not correct if staggered grids are used ASSERT3(not mesh->StaggerGrids); - Jpar(r.ind, jy, jz) = 2. * jsheath - Jpar(r.ind, mesh->yend, jz); + Jpar_fa(r.ind, jy, jz) = 2. * jsheath - Jpar_fa(r.ind, mesh->yend, jz); } } } + + // Shift back from field aligned coordinates + phi = fromFieldAligned(phi_fa); + P = fromFieldAligned(P_fa); + Jpar = fromFieldAligned(Jpar_fa); } //////////////////////////////////////////////////// @@ -1487,15 +1500,16 @@ class ELMpb : public PhysicsModel { } } else { // Vector potential - ddt(Psi) = -Grad_parP(phi, loc) + eta * Jpar; + ddt(Psi) = -Grad_parP(phi * B0, loc) / B0 + eta * Jpar; if (eHall) { // electron parallel pressure ddt(Psi) += 0.25 * delta_i - * (Grad_parP(P, loc) + bracket(interp_to(P0, loc), Psi, bm_mag)); + * (Grad_parP(B0 * P, loc) / B0 + + bracket(interp_to(P0, loc), Psi, bm_mag) * B0); } if (diamag_phi0) { // Equilibrium flow - ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb); + ddt(Psi) -= bracket(interp_to(phi0, loc), Psi, bm_exb) * B0; } if (withflow) { // net flow diff --git a/examples/elm-pb/makefile b/examples/elm-pb/makefile deleted file mode 100644 index ea19cf6f83..0000000000 --- a/examples/elm-pb/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../ - -SOURCEC = elm_pb.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/elm-pb/plot_linear.py b/examples/elm-pb/plot_linear.py new file mode 100644 index 0000000000..42047ec5dc --- /dev/null +++ b/examples/elm-pb/plot_linear.py @@ -0,0 +1,85 @@ +# Plots an analysis of the linear growth rate +# +# Input argument is the directory containing data files. +# +# Example: +# $ python plot_linear.py data/ +# + +from boutdata import collect +import numpy as np +import matplotlib.pyplot as plt +import os +import sys + +if len(sys.argv) != 2: + raise ValueError(f"Usage: {sys.argv[0]} path") + +# Path to the data +path = sys.argv[1] + +# Read pressure at last time point, to find peak +p = collect("P", path=path, tind=-1).squeeze() +prms = np.sqrt(np.mean(p**2, axis=-1)) + +pyprof = np.amax(prms, axis=0) +yind = np.argmax(pyprof) +pxprof = prms[:, yind] +xind = np.argmax(pxprof) +print(f"Peak amplitude at x = {xind}, y = {yind}") + +# Read pressure time history at index of peak amplitude +p = collect("P", path=path, xind=xind, yind=yind).squeeze() + +# p = p[:,:-1] # Remove point in Z + +prms = np.sqrt(np.mean(p**2, axis=-1)) + +t = collect("t_array", path=path) +dt = t[1] - t[0] + +gamma = np.gradient(np.log(prms)) / dt +growth_rate = np.mean(gamma[len(gamma) // 2 :]) +growth_rate_std = np.std(gamma[len(gamma) // 2 :]) + +print(f"Mean growth rate: {growth_rate} +/- {growth_rate_std}") + +fig, axs = plt.subplots(2, 2) + +ax = axs[0, 0] +ax.plot(pyprof) +ax.set_xlabel("Y index") +ax.set_ylabel("RMS pressure") +ax.axvline(yind, linestyle="--", color="k") +ax.text(yind, 0.5 * pyprof[yind], f"y = {yind}") + +ax = axs[0, 1] +ax.plot(pxprof) +ax.set_xlabel("X index") +ax.set_ylabel("RMS pressure") +ax.axvline(xind, linestyle="--", color="k") +ax.text(xind, 0.5 * pxprof[xind], f"x = {xind}") + +ax = axs[1, 0] +ax.plot(t, prms) +ax.set_xlabel(r"Time [$\tau_A$]") +ax.set_ylabel("RMS pressure") +ax.set_yscale("log") +ax.plot(t, prms[-1] * np.exp(growth_rate * (t - t[-1])), "--k") + +ax = axs[1, 1] +ax.plot(t, gamma) +ax.set_xlabel(r"Time [$\tau_A$]") +ax.set_ylabel("Growth rate [$\omega_A$]") +ax.axhline(growth_rate, linestyle="--", color="k") +ax.text( + (t[-1] + t[0]) / 4, + growth_rate * 1.2, + rf"$\gamma = {growth_rate:.3f}\pm {growth_rate_std:.3f} \omega_A$", +) + +plt.savefig(os.path.join(path, "linear_growth.pdf")) +plt.savefig(os.path.join(path, "linear_growth.png")) + +plt.tight_layout() +plt.show() diff --git a/examples/em-drift/makefile b/examples/em-drift/makefile deleted file mode 100644 index e9c69ca443..0000000000 --- a/examples/em-drift/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP ?= ../.. - -SOURCEC = 2fluid.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/fci-wave-logn/boundary/BOUT.inp b/examples/fci-wave-logn/boundary/BOUT.inp index 11e57ec47d..0632aa949b 100644 --- a/examples/fci-wave-logn/boundary/BOUT.inp +++ b/examples/fci-wave-logn/boundary/BOUT.inp @@ -20,7 +20,7 @@ expand_divergence = false background = 1e-06 # Background density [all] -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 bndry_all = neumann [n] @@ -28,15 +28,15 @@ bndry_all = neumann zl = z / (2*pi) function = fciwave:background + 1e-3*exp(-((x-0.7)/0.1)^2 - ((zl-0.3)/0.1)^2) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [logn] function = log(n:function) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [v] diff --git a/examples/fci-wave-logn/div-integrate/BOUT.inp b/examples/fci-wave-logn/div-integrate/BOUT.inp index a37bf3e2a5..66bdbce5f2 100644 --- a/examples/fci-wave-logn/div-integrate/BOUT.inp +++ b/examples/fci-wave-logn/div-integrate/BOUT.inp @@ -20,7 +20,7 @@ expand_divergence = false background = 1e-06 # Background density [all] -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 bndry_all = neumann [n] @@ -28,15 +28,15 @@ bndry_all = neumann zl = z / (2*pi) function = fciwave:background + 1e-3*exp(-((x-0.7)/0.1)^2 - ((zl-0.3)/0.1)^2) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [logn] function = log(n:function) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [v] diff --git a/examples/fci-wave-logn/expanded/BOUT.inp b/examples/fci-wave-logn/expanded/BOUT.inp index 3a2935c6e8..e084511d24 100644 --- a/examples/fci-wave-logn/expanded/BOUT.inp +++ b/examples/fci-wave-logn/expanded/BOUT.inp @@ -20,7 +20,7 @@ expand_divergence = true background = 1e-06 # Background density [all] -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 bndry_all = neumann [n] @@ -28,15 +28,15 @@ bndry_all = neumann zl = z / (2*pi) function = fciwave:background + 1e-3*exp(-((x-0.7)/0.1)^2 - ((zl-0.3)/0.1)^2) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [logn] function = log(n:function) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [v] diff --git a/examples/fci-wave-logn/fci-wave.cxx b/examples/fci-wave-logn/fci-wave.cxx index 731897ad4e..2ea9048421 100644 --- a/examples/fci-wave-logn/fci-wave.cxx +++ b/examples/fci-wave-logn/fci-wave.cxx @@ -62,7 +62,7 @@ class FCIwave : public PhysicsModel { // Neumann boundaries simplifies parallel derivatives Bxyz.applyBoundary("neumann"); - Bxyz.applyParallelBoundary("parallel_neumann"); + Bxyz.applyParallelBoundary("parallel_neumann_o2"); SAVE_ONCE(Bxyz); Options::getRoot()->getSection("fciwave")->get("expand_divergence", expand_divergence, diff --git a/examples/fci-wave-logn/makefile b/examples/fci-wave-logn/makefile deleted file mode 100644 index 24c0928db5..0000000000 --- a/examples/fci-wave-logn/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = fci-wave.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/fci-wave/div-integrate/BOUT.inp b/examples/fci-wave/div-integrate/BOUT.inp index eb41d5f228..68f2326f52 100644 --- a/examples/fci-wave/div-integrate/BOUT.inp +++ b/examples/fci-wave/div-integrate/BOUT.inp @@ -21,7 +21,7 @@ log_density = false # Evolve log(n)? background = 1e-06 # Background density [all] -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 bndry_all = neumann [n] @@ -29,15 +29,15 @@ bndry_all = neumann zl = z / (2*pi) function = fciwave:background + 1e-3*exp(-((x-0.7)/0.1)^2 - ((zl-0.3)/0.1)^2) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [logn] function = log(n:function) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [v] diff --git a/examples/fci-wave/div/BOUT.inp b/examples/fci-wave/div/BOUT.inp index 70b60757eb..3f497df6c7 100644 --- a/examples/fci-wave/div/BOUT.inp +++ b/examples/fci-wave/div/BOUT.inp @@ -21,7 +21,7 @@ log_density = false # Evolve log(n)? background = 1e-06 # Background density [all] -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 bndry_all = neumann [n] @@ -29,15 +29,15 @@ bndry_all = neumann zl = z / (2*pi) function = fciwave:background + 1e-3*exp(-((x-0.7)/0.1)^2 - ((zl-0.3)/0.1)^2) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [logn] function = log(n:function) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [v] diff --git a/examples/fci-wave/fci-wave.cxx b/examples/fci-wave/fci-wave.cxx index 226b52c808..2fd383ed3f 100644 --- a/examples/fci-wave/fci-wave.cxx +++ b/examples/fci-wave/fci-wave.cxx @@ -69,7 +69,7 @@ class FCIwave : public PhysicsModel { // Neumann boundaries simplifies parallel derivatives Bxyz.applyBoundary("neumann"); - Bxyz.applyParallelBoundary("parallel_neumann"); + Bxyz.applyParallelBoundary("parallel_neumann_o2"); SAVE_ONCE(Bxyz); SOLVE_FOR(nv); diff --git a/examples/fci-wave/logn/BOUT.inp b/examples/fci-wave/logn/BOUT.inp index f97d8cc891..26f8a99d63 100644 --- a/examples/fci-wave/logn/BOUT.inp +++ b/examples/fci-wave/logn/BOUT.inp @@ -21,7 +21,7 @@ log_density = true # Evolve log(n)? background = 1e-06 # Background density [all] -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 bndry_all = neumann [n] @@ -29,15 +29,15 @@ bndry_all = neumann zl = z / (2*pi) function = fciwave:background + 1e-3*exp(-((x-0.7)/0.1)^2 - ((zl-0.3)/0.1)^2) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [logn] function = log(n:function) -bndry_par_yup = parallel_neumann -bndry_par_ydown = parallel_neumann +bndry_par_yup = parallel_neumann_o2 +bndry_par_ydown = parallel_neumann_o2 [nv] diff --git a/examples/fci-wave/makefile b/examples/fci-wave/makefile deleted file mode 100644 index 24c0928db5..0000000000 --- a/examples/fci-wave/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = fci-wave.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/finite-volume/diffusion/makefile b/examples/finite-volume/diffusion/makefile deleted file mode 100644 index c633a109d9..0000000000 --- a/examples/finite-volume/diffusion/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = diffusion.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/finite-volume/fluid/makefile b/examples/finite-volume/fluid/makefile deleted file mode 100644 index 4effb80b45..0000000000 --- a/examples/finite-volume/fluid/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = fluid.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/finite-volume/test/makefile b/examples/finite-volume/test/makefile deleted file mode 100644 index 96b5469333..0000000000 --- a/examples/finite-volume/test/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = finite_volume.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/gas-compress/makefile b/examples/gas-compress/makefile deleted file mode 100644 index 029f9335a1..0000000000 --- a/examples/gas-compress/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = gas_compress.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/gravity_reduced/makefile b/examples/gravity_reduced/makefile deleted file mode 100644 index eb5a62641a..0000000000 --- a/examples/gravity_reduced/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = gravity_reduced.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/gyro-gem/doc/makefile b/examples/gyro-gem/doc/makefile deleted file mode 100644 index 95a4b4d896..0000000000 --- a/examples/gyro-gem/doc/makefile +++ /dev/null @@ -1,11 +0,0 @@ - -DOCS=gem.pdf - -all:$(DOCS) - -%.pdf: %.tex - latexmk -pdf $< -interaction=batchmode - -.PHONY: clean -clean: - latexmk -C diff --git a/examples/gyro-gem/makefile b/examples/gyro-gem/makefile deleted file mode 100644 index 709cf2d5fa..0000000000 --- a/examples/gyro-gem/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = gem.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/hasegawa-wakatani-3d/makefile b/examples/hasegawa-wakatani-3d/makefile deleted file mode 100644 index 8f33b716b9..0000000000 --- a/examples/hasegawa-wakatani-3d/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../.. - -SOURCEC = hw.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/hasegawa-wakatani/makefile b/examples/hasegawa-wakatani/makefile deleted file mode 100644 index 34395b1bf0..0000000000 --- a/examples/hasegawa-wakatani/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = hw.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/invertable_operator/makefile b/examples/invertable_operator/makefile deleted file mode 100644 index ff5ec8c809..0000000000 --- a/examples/invertable_operator/makefile +++ /dev/null @@ -1,11 +0,0 @@ -BOUT_TOP ?= ../.. - -SOURCEC = invertable_operator.cxx - -target: requires_petsc invertable_operator - -requires_petsc: - @test $$($(BOUT_TOP)/bin/bout-config --has-petsc ) = yes || \ - (echo "ERROR: This example requires PETSc. Please compile BOUT++ with PETSc." ; exit 1) - -include $(BOUT_TOP)/make.config diff --git a/examples/jorek-compare/doc/makefile b/examples/jorek-compare/doc/makefile deleted file mode 100644 index 66c36824ae..0000000000 --- a/examples/jorek-compare/doc/makefile +++ /dev/null @@ -1,11 +0,0 @@ - -DOCS=jorek_compare.pdf - -all:$(DOCS) - -%.pdf: %.tex - latexmk -pdf $< -interaction=batchmode - -.PHONY: clean -clean: - latexmk -C diff --git a/examples/jorek-compare/makefile b/examples/jorek-compare/makefile deleted file mode 100644 index 4d0898da1e..0000000000 --- a/examples/jorek-compare/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = jorek_compare.cxx - -include $(BOUT_TOP)/make.config \ No newline at end of file diff --git a/examples/lapd-drift/makefile b/examples/lapd-drift/makefile deleted file mode 100644 index abb567e24b..0000000000 --- a/examples/lapd-drift/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = lapd_drift.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/laplace-petsc3d/data/BOUT.inp b/examples/laplace-petsc3d/data/BOUT.inp index 86a52c69f2..7e81d992a2 100644 --- a/examples/laplace-petsc3d/data/BOUT.inp +++ b/examples/laplace-petsc3d/data/BOUT.inp @@ -6,7 +6,7 @@ mz = 128 function = mixmode(x, 1.)*mixmode(y, 2.)*mixmode(z, 3.) bndry_xin = none bndry_xout = none -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 [rhs] function = mixmode(x, 4.)*mixmode(y, 5.)*mixmode(z, 6.) @@ -22,7 +22,7 @@ function = 1. + .1*mixmode(x, 10.)*mixmode(y, 11.)*mixmode(z, 12.) [C2] #function = 0. function = .1*mixmode(x, 13.)*mixmode(y, 14.)*mixmode(z, 15.) -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 [A] function = 0.0 @@ -46,7 +46,7 @@ transform_from_field_aligned = false [initial] bndry_xin = neumann bndry_xout = neumann -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 [input1] function = mixmode(x, 1.)*mixmode(z, 2.) diff --git a/examples/laplace-petsc3d/makefile b/examples/laplace-petsc3d/makefile deleted file mode 100644 index ad943fe51c..0000000000 --- a/examples/laplace-petsc3d/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP ?= ../.. - -SOURCEC = test-laplace3d.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/laplace-petsc3d/makefile.create-initial-profiles b/examples/laplace-petsc3d/makefile.create-initial-profiles deleted file mode 100644 index 1e0f564626..0000000000 --- a/examples/laplace-petsc3d/makefile.create-initial-profiles +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP ?= ../.. - -SOURCEC = create-initial-profiles.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/laplacexy/alfven-wave/makefile b/examples/laplacexy/alfven-wave/makefile deleted file mode 100644 index cc53facb8e..0000000000 --- a/examples/laplacexy/alfven-wave/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = alfven.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/laplacexy/laplace_perp/makefile b/examples/laplacexy/laplace_perp/makefile deleted file mode 100644 index 76f2d7cc5b..0000000000 --- a/examples/laplacexy/laplace_perp/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = test.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/laplacexy/simple/makefile b/examples/laplacexy/simple/makefile deleted file mode 100644 index d3da2c0196..0000000000 --- a/examples/laplacexy/simple/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = test-laplacexy.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/make-script/makefile b/examples/make-script/makefile index ac5f4e96a4..b941125bce 100644 --- a/examples/make-script/makefile +++ b/examples/make-script/makefile @@ -22,11 +22,11 @@ LDFLAGS:=$(shell bout-config --libs) $(TARGET): makefile $(OBJ) @echo " Linking" $(TARGET) - @$(LD) -o $(TARGET) $(OBJ) $(LDFLAGS) + $(LD) -o $(TARGET) $(OBJ) $(LDFLAGS) %.o: %.cxx @echo " Compiling " $(@F:.o=.cxx) - @$(CXX) $(CFLAGS) -c $(@F:.o=.cxx) -o $@ + $(CXX) $(CFLAGS) -c $(@F:.o=.cxx) -o $@ .PHONY: clean clean: diff --git a/examples/monitor-newapi/makefile b/examples/monitor-newapi/makefile deleted file mode 100644 index 0ec013a133..0000000000 --- a/examples/monitor-newapi/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = monitor.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/monitor/makefile b/examples/monitor/makefile deleted file mode 100644 index 0ec013a133..0000000000 --- a/examples/monitor/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = monitor.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/orszag-tang/makefile b/examples/orszag-tang/makefile deleted file mode 100644 index 9796b1c7a7..0000000000 --- a/examples/orszag-tang/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = mhd.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/performance/arithmetic/arithmetic.cxx b/examples/performance/arithmetic/arithmetic.cxx index 583c857e28..fc2357978a 100644 --- a/examples/performance/arithmetic/arithmetic.cxx +++ b/examples/performance/arithmetic/arithmetic.cxx @@ -18,6 +18,7 @@ using namespace std::chrono; SteadyClock start = steady_clock::now(); \ { __VA_ARGS__; } \ Duration diff = steady_clock::now() - start; \ + diff *= 1000 * 1000; \ elapsed.min = diff > elapsed.min ? elapsed.min : diff; \ elapsed.max = diff < elapsed.max ? elapsed.max : diff; \ elapsed.count++; \ @@ -38,6 +39,8 @@ class Arithmetic : public PhysicsModel { Field3D a = 1.0; Field3D b = 2.0; Field3D c = 3.0; + a.setRegion("RGN_ALL"); + b.setRegion("RGN_NOBNDRY"); Field3D result1, result2, result3, result4; @@ -48,7 +51,7 @@ class Arithmetic : public PhysicsModel { Durations elapsed1 = dur_init, elapsed2 = dur_init, elapsed3 = dur_init, elapsed4 = dur_init; - for (int ik = 0; ik < 1e2; ++ik) { + for (int ik = 0; ik < 1e3; ++ik) { TIMEIT(elapsed1, result1 = 2. * a + b * c;); // Using C loops @@ -77,12 +80,13 @@ class Arithmetic : public PhysicsModel { } output.enable(); - output << "TIMING\n======\n"; + output << "TIMING | minimum | mean | maximum\n" + << "----------- | ---------- | ---------- | ----------\n"; //#define PRINT(str,elapsed) output << str << elapsed.min.count()<< //elapsed.avg.count()<< elapsed.max.count() << endl; -#define PRINT(str, elapsed) \ - output.write("{:s} {:8.3g} {:8.3g} {:8.3g}\n", str, elapsed.min.count(), \ - elapsed.avg.count(), elapsed.max.count()) +#define PRINT(str, elapsed) \ + output.write("{:s} | {:7.3f} us | {:7.3f} us | {:7.3f} us\n", str, \ + elapsed.min.count(), elapsed.avg.count(), elapsed.max.count()) PRINT("Fields: ", elapsed1); PRINT("C loop: ", elapsed2); PRINT("Templates: ", elapsed3); diff --git a/examples/performance/arithmetic/makefile b/examples/performance/arithmetic/makefile deleted file mode 100644 index c9e6f1e69c..0000000000 --- a/examples/performance/arithmetic/makefile +++ /dev/null @@ -1,10 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = arithmetic.cxx - -include $(BOUT_TOP)/make.config - - -run:arithmetic - ./arithmetic -q -q -q diff --git a/examples/performance/arithmetic_3d2d/makefile b/examples/performance/arithmetic_3d2d/makefile deleted file mode 100644 index 386ab242e6..0000000000 --- a/examples/performance/arithmetic_3d2d/makefile +++ /dev/null @@ -1,10 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = arithmetic_3d2d.cxx - -include $(BOUT_TOP)/make.config - - -run:arithmetic_3d2d - ./arithmetic_3d2d -q -q -q diff --git a/examples/performance/bracket/makefile b/examples/performance/bracket/makefile deleted file mode 100644 index 3559c27e2d..0000000000 --- a/examples/performance/bracket/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = bracket.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/performance/communications/makefile b/examples/performance/communications/makefile deleted file mode 100644 index 80cdd9062f..0000000000 --- a/examples/performance/communications/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP ?= ../../.. - -SOURCEC = communications.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/performance/ddx/makefile b/examples/performance/ddx/makefile deleted file mode 100644 index 52f6ed7dc0..0000000000 --- a/examples/performance/ddx/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = ddx.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/performance/ddy/makefile b/examples/performance/ddy/makefile deleted file mode 100644 index 57b502450a..0000000000 --- a/examples/performance/ddy/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = ddy.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/performance/ddz/makefile b/examples/performance/ddz/makefile deleted file mode 100644 index 5f7aefa6cc..0000000000 --- a/examples/performance/ddz/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = ddz.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/performance/iterator-offsets/iterator-offsets.cxx b/examples/performance/iterator-offsets/iterator-offsets.cxx index 08149f855e..2376b63578 100644 --- a/examples/performance/iterator-offsets/iterator-offsets.cxx +++ b/examples/performance/iterator-offsets/iterator-offsets.cxx @@ -73,7 +73,7 @@ int main(int argc, char** argv) { #if BOUT_USE_OPENMP ITERATOR_TEST_BLOCK( "Nested loop (omp)", - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for(int i=0;iLocalNx;++i) { for (int j = mesh->ystart; j < mesh->yend; ++j) { for (int k = 0; k < mesh->LocalNz; ++k) { @@ -98,7 +98,7 @@ int main(int argc, char** argv) { deriv(a, result, "RGN_NOY");); ITERATOR_TEST_BLOCK( - "Region with stencil", BOUT_OMP(parallel) { + "Region with stencil", BOUT_OMP_PERF(parallel) { stencil s; BOUT_FOR_INNER(i, mesh->getRegion3D("RGN_NOY")) { s.m = a[i.ym()]; @@ -110,7 +110,7 @@ int main(int argc, char** argv) { }); ITERATOR_TEST_BLOCK( - "Region with stencil and function pointer", BOUT_OMP(parallel) { + "Region with stencil and function pointer", BOUT_OMP_PERF(parallel) { stencil s; BOUT_FOR_INNER(i, mesh->getRegion3D("RGN_NOY")) { s.m = a[i.ym()]; diff --git a/examples/performance/iterator-offsets/makefile b/examples/performance/iterator-offsets/makefile deleted file mode 100644 index 94dac859f6..0000000000 --- a/examples/performance/iterator-offsets/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = iterator-offsets.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/performance/iterator/iterator.cxx b/examples/performance/iterator/iterator.cxx index 7f9eb7ce1f..af1163d927 100644 --- a/examples/performance/iterator/iterator.cxx +++ b/examples/performance/iterator/iterator.cxx @@ -66,7 +66,7 @@ int main(int argc, char** argv) { "C loop", for (int j = 0; j < len; ++j) { rd[j] = ad[j] + bd[j]; };); #if BOUT_USE_OPENMP ITERATOR_TEST_BLOCK("C loop (omp)", - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for(int j=0;jLocalNx;++i) { for (int j = 0; j < mesh->LocalNy; ++j) { for (int k = 0; k < mesh->LocalNz; ++k) { diff --git a/examples/performance/iterator/makefile b/examples/performance/iterator/makefile deleted file mode 100644 index 33a11d30be..0000000000 --- a/examples/performance/iterator/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = iterator.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/performance/laplace/makefile b/examples/performance/laplace/makefile deleted file mode 100644 index 3ff28a130e..0000000000 --- a/examples/performance/laplace/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = laplace.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/performance/tuning_regionblocksize/makefile b/examples/performance/tuning_regionblocksize/makefile deleted file mode 100644 index 6f906e3793..0000000000 --- a/examples/performance/tuning_regionblocksize/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = tuning_regionblocksize.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/preconditioning/wave/makefile b/examples/preconditioning/wave/makefile deleted file mode 100644 index 095c893d8e..0000000000 --- a/examples/preconditioning/wave/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP ?= ../../.. - -SOURCEC = test_precon.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/reconnect-2field/makefile b/examples/reconnect-2field/makefile deleted file mode 100644 index 0b7745f5af..0000000000 --- a/examples/reconnect-2field/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = 2field.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/shear-alfven-wave/makefile b/examples/shear-alfven-wave/makefile deleted file mode 100644 index 92ac3ce50d..0000000000 --- a/examples/shear-alfven-wave/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = 2fluid.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/shear-alfven-wave/orig_test.idl.dat b/examples/shear-alfven-wave/orig_test.idl.dat deleted file mode 100644 index 4e2a7a18fa..0000000000 Binary files a/examples/shear-alfven-wave/orig_test.idl.dat and /dev/null differ diff --git a/examples/staggered_grid/makefile b/examples/staggered_grid/makefile deleted file mode 100644 index e00eaecd74..0000000000 --- a/examples/staggered_grid/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = test_staggered.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/subsampling/makefile b/examples/subsampling/makefile deleted file mode 100644 index 0ec013a133..0000000000 --- a/examples/subsampling/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = monitor.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/tokamak-2fluid/makefile b/examples/tokamak-2fluid/makefile deleted file mode 100644 index 92ac3ce50d..0000000000 --- a/examples/tokamak-2fluid/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = 2fluid.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/uedge-benchmark/makefile b/examples/uedge-benchmark/makefile deleted file mode 100644 index 4c8a72d394..0000000000 --- a/examples/uedge-benchmark/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = ue_bmark.cxx - -include $(BOUT_TOP)/make.config diff --git a/examples/uedge-benchmark/result_080917.idl b/examples/uedge-benchmark/result_080917.idl deleted file mode 100644 index 240ee3d94e..0000000000 Binary files a/examples/uedge-benchmark/result_080917.idl and /dev/null differ diff --git a/examples/uedge-benchmark/ue_bmk.idl b/examples/uedge-benchmark/ue_bmk.idl deleted file mode 100644 index 721e9a2f82..0000000000 Binary files a/examples/uedge-benchmark/ue_bmk.idl and /dev/null differ diff --git a/examples/wave-slab/makefile b/examples/wave-slab/makefile deleted file mode 100644 index b20fcf6c8e..0000000000 --- a/examples/wave-slab/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../.. - -SOURCEC = wave_slab.cxx - -include $(BOUT_TOP)/make.config diff --git a/include/bout/adios_object.hxx b/include/bout/adios_object.hxx new file mode 100755 index 0000000000..4750930373 --- /dev/null +++ b/include/bout/adios_object.hxx @@ -0,0 +1,83 @@ +/*!************************************************************************ + * Provides access to the ADIOS library, handling initialisation and + * finalisation. + * + * Usage + * ----- + * + * #include + * + **************************************************************************/ + +#ifndef ADIOS_OBJECT_HXX +#define ADIOS_OBJECT_HXX + +#include "bout/build_config.hxx" + +#if BOUT_HAS_ADIOS2 + +#include +#include +#include + +namespace bout { + +void ADIOSInit(MPI_Comm comm); +void ADIOSInit(const std::string configFile, MPI_Comm comm); +void ADIOSFinalize(); + +using ADIOSPtr = std::shared_ptr; +using EnginePtr = std::shared_ptr; +using IOPtr = std::shared_ptr; + +ADIOSPtr GetADIOSPtr(); +IOPtr GetIOPtr(const std::string IOName); + +class ADIOSStream { +public: + adios2::IO io; + adios2::Engine engine; + adios2::Variable vTime; + adios2::Variable vStep; + int adiosStep = 0; + bool isInStep = false; // true if BeginStep was called and EndStep was not yet called + + /** create or return the ADIOSStream based on the target file name */ + static ADIOSStream& ADIOSGetStream(const std::string& fname); + + ~ADIOSStream(); + + template + adios2::Variable GetValueVariable(const std::string& varname) { + auto v = io.InquireVariable(varname); + if (!v) { + v = io.DefineVariable(varname); + } + return v; + } + + template + adios2::Variable GetArrayVariable(const std::string& varname, adios2::Dims& shape) { + adios2::Variable v = io.InquireVariable(varname); + if (!v) { + adios2::Dims start(shape.size()); + v = io.DefineVariable(varname, shape, start, shape); + } else { + v.SetShape(shape); + } + return v; + } + +private: + ADIOSStream(const std::string fname) : fname(fname){}; + std::string fname; +}; + +/** Set user parameters for an IO group */ +void ADIOSSetParameters(const std::string& input, const char delimKeyValue, + const char delimItem, adios2::IO& io); + +} // namespace bout + +#endif //BOUT_HAS_ADIOS2 +#endif //ADIOS_OBJECT_HXX diff --git a/include/bout/array.hxx b/include/bout/array.hxx index 060b4900a1..0caaed9c86 100644 --- a/include/bout/array.hxx +++ b/include/bout/array.hxx @@ -23,15 +23,15 @@ * o Added Umpire support, in multiple iterations/variations */ -#ifndef __ARRAY_H__ -#define __ARRAY_H__ +#ifndef BOUT_ARRAY_H +#define BOUT_ARRAY_H #include #include #include #include -#ifdef _OPENMP +#if BOUT_USE_OPENMP #include #endif @@ -375,22 +375,14 @@ private: * @param[in] cleanup If set to true, deletes all dataBlock and clears the store */ static storeType& store(bool cleanup = false) { -#ifdef _OPENMP static arenaType arena(omp_get_max_threads()); -#else - static arenaType arena(1); -#endif if (!cleanup) { -#ifdef _OPENMP return arena[omp_get_thread_num()]; -#else - return arena[0]; -#endif } // Clean by deleting all data -- possible that just stores.clear() is // sufficient rather than looping over each entry. - BOUT_OMP(single) + BOUT_OMP_SAFE(single) { for (auto& stores : arena) { for (auto& p : stores) { @@ -486,4 +478,4 @@ bool operator==(const Array& lhs, const Array& rhs) { return std::equal(lhs.begin(), lhs.end(), rhs.begin()); } -#endif // __ARRAY_H__ +#endif // BOUT_ARRAY_H diff --git a/include/bout/assert.hxx b/include/bout/assert.hxx index 233641966b..653c44ed42 100644 --- a/include/bout/assert.hxx +++ b/include/bout/assert.hxx @@ -14,8 +14,8 @@ * */ -#ifndef __BOUT_ASSERT_H__ -#define __BOUT_ASSERT_H__ +#ifndef BOUT_ASSERT_H +#define BOUT_ASSERT_H #include "bout/boutexception.hxx" @@ -65,4 +65,4 @@ #define ASSERT3(condition) #endif -#endif // __BOUT_ASSERT_H__ +#endif // BOUT_ASSERT_H diff --git a/include/bout/boundary_factory.hxx b/include/bout/boundary_factory.hxx index 208b7cdb61..5f1f6e06a6 100644 --- a/include/bout/boundary_factory.hxx +++ b/include/bout/boundary_factory.hxx @@ -1,13 +1,16 @@ class BoundaryFactory; -#ifndef __BNDRY_FACTORY_H__ -#define __BNDRY_FACTORY_H__ +#ifndef BOUT_BNDRY_FACTORY_H +#define BOUT_BNDRY_FACTORY_H -#include "bout/boundary_op.hxx" -#include "bout/boundary_region.hxx" -#include "bout/parallel_boundary_op.hxx" -#include "bout/parallel_boundary_region.hxx" +class BoundaryOpBase; +class BoundaryOpPar; +class BoundaryOp; +class BoundaryRegionBase; +class BoundaryRegionPar; +class BoundaryRegion; +class BoundaryModifier; #include #include @@ -126,4 +129,4 @@ private: // BoundaryModifier* findBoundaryMod(const string &s); }; -#endif // __BNDRY_FACTORY_H__ +#endif // BOUT_BNDRY_FACTORY_H diff --git a/include/bout/boundary_op.hxx b/include/bout/boundary_op.hxx index 035caa2778..1a9aa1ad68 100644 --- a/include/bout/boundary_op.hxx +++ b/include/bout/boundary_op.hxx @@ -78,8 +78,9 @@ public: virtual void apply_ddt(Vector3D& f) { apply(ddt(f)); } BoundaryRegion* bndry; - bool - apply_to_ddt; // True if this boundary condition should be applied on the time derivatives, false if it should be applied to the field values + // True if this boundary condition should be applied on the time derivatives + // false if it should be applied to the field values + bool apply_to_ddt; }; class BoundaryModifier : public BoundaryOp { diff --git a/include/bout/boundary_region.hxx b/include/bout/boundary_region.hxx index 542460580c..58de12045e 100644 --- a/include/bout/boundary_region.hxx +++ b/include/bout/boundary_region.hxx @@ -1,8 +1,8 @@ class BoundaryRegion; -#ifndef __BNDRY_REGION_H__ -#define __BNDRY_REGION_H__ +#ifndef BOUT_BNDRY_REGION_H +#define BOUT_BNDRY_REGION_H #include #include @@ -142,4 +142,4 @@ private: int xs, xe; }; -#endif // __BNDRY_REGION_H__ +#endif // BOUT_BNDRY_REGION_H diff --git a/include/bout/boundary_standard.hxx b/include/bout/boundary_standard.hxx index 96d43de24d..b1116e159f 100644 --- a/include/bout/boundary_standard.hxx +++ b/include/bout/boundary_standard.hxx @@ -1,7 +1,7 @@ /// Some standard boundary conditions -#ifndef __BNDRY_STD_H__ -#define __BNDRY_STD_H__ +#ifndef BOUT_BNDRY_STD_H +#define BOUT_BNDRY_STD_H #include "bout/boundary_op.hxx" #include "bout/bout_types.hxx" @@ -516,4 +516,4 @@ public: private: }; -#endif // __BNDRY_STD_H__ +#endif // BOUT_BNDRY_STD_H diff --git a/include/bout/bout.hxx b/include/bout/bout.hxx index 5e718dde33..09433bcc3b 100644 --- a/include/bout/bout.hxx +++ b/include/bout/bout.hxx @@ -2,8 +2,6 @@ * * @mainpage BOUT++ * - * @version 3.0 - * * @par Description * Framework for the solution of partial differential * equations, in particular fluid models in plasma physics. @@ -33,9 +31,10 @@ * **************************************************************************/ -#ifndef __BOUT_H__ -#define __BOUT_H__ +#ifndef BOUT_H +#define BOUT_H +// IWYU pragma: begin_keep, begin_export #include "bout/build_config.hxx" #include "bout/boutcomm.hxx" @@ -44,7 +43,7 @@ #include "bout/field3d.hxx" #include "bout/globals.hxx" #include "bout/mesh.hxx" -#include "bout/options_netcdf.hxx" +#include "bout/options_io.hxx" #include "bout/output.hxx" #include "bout/smoothing.hxx" // Smoothing functions #include "bout/solver.hxx" @@ -55,6 +54,7 @@ #include "bout/vector3d.hxx" #include "bout/version.hxx" #include "bout/where.hxx" +// IWYU pragma: end_keep, end_export // BOUT++ main functions @@ -206,4 +206,4 @@ private: */ int BoutFinalise(bool write_settings = true); -#endif // __BOUT_H__ +#endif // BOUT_H diff --git a/include/bout/bout_enum_class.hxx b/include/bout/bout_enum_class.hxx index ef251b4c2f..585e5b020e 100644 --- a/include/bout/bout_enum_class.hxx +++ b/include/bout/bout_enum_class.hxx @@ -19,8 +19,8 @@ * along with BOUT++. If not, see . **************************************************************************/ -#ifndef __BOUT_ENUM_CLASS_H__ -#define __BOUT_ENUM_CLASS_H__ +#ifndef BOUT_ENUM_CLASS_H +#define BOUT_ENUM_CLASS_H #include "bout/boutexception.hxx" #include "bout/macro_for_each.hxx" @@ -86,7 +86,11 @@ BOUT_ENUM_CLASS_MAP_ARGS(BOUT_STR_ENUM_CLASS, enumname, __VA_ARGS__)}; \ auto found = fromString_map.find(s); \ if (found == fromString_map.end()) { \ - throw BoutException("Did not find enum {:s}", s); \ + std::string valid_values {}; \ + for (auto const& entry : fromString_map) { \ + valid_values += std::string(" ") + entry.first; \ + } \ + throw BoutException("Did not find enum {:s}. Valid values: {:s}", s, valid_values); \ } \ return found->second; \ } \ @@ -100,4 +104,4 @@ return out << toString(e); \ } -#endif // __BOUT_ENUM_CLASS_H__ +#endif // BOUT_ENUM_CLASS_H diff --git a/include/bout/bout_types.hxx b/include/bout/bout_types.hxx index 5a00b5144b..c1f06fca7c 100644 --- a/include/bout/bout_types.hxx +++ b/include/bout/bout_types.hxx @@ -19,8 +19,8 @@ * along with BOUT++. If not, see . **************************************************************************/ -#ifndef __BOUT_TYPES_H__ -#define __BOUT_TYPES_H__ +#ifndef BOUT_TYPES_H +#define BOUT_TYPES_H #include #include @@ -140,4 +140,4 @@ struct enumWrapper { /// Boundary condition function using FuncPtr = BoutReal (*)(BoutReal t, BoutReal x, BoutReal y, BoutReal z); -#endif // __BOUT_TYPES_H__ +#endif // BOUT_TYPES_H diff --git a/include/bout/boutcomm.hxx b/include/bout/boutcomm.hxx index fea401af02..9342d29741 100644 --- a/include/bout/boutcomm.hxx +++ b/include/bout/boutcomm.hxx @@ -27,8 +27,8 @@ class BoutComm; -#ifndef __BOUTCOMM_H__ -#define __BOUTCOMM_H__ +#ifndef BOUT_BOUTCOMM_H +#define BOUT_BOUTCOMM_H #include @@ -68,4 +68,4 @@ private: static BoutComm* instance; ///< The only instance of this class (Singleton) }; -#endif // __BOUTCOMM_H__ +#endif // BOUT_BOUTCOMM_H diff --git a/include/bout/boutexception.hxx b/include/bout/boutexception.hxx index 5b8a421692..238c88654c 100644 --- a/include/bout/boutexception.hxx +++ b/include/bout/boutexception.hxx @@ -1,17 +1,13 @@ +#ifndef BOUT_EXCEPTION_H +#define BOUT_EXCEPTION_H -class BoutException; - -#ifndef __BOUT_EXCEPTION_H__ -#define __BOUT_EXCEPTION_H__ - -#include "bout/build_config.hxx" +#include "bout/build_defines.hxx" +#include #include #include #include -#include "bout/format.hxx" - #include "fmt/core.h" /// Throw BoutRhsFail with \p message if any one process has non-zero @@ -34,13 +30,11 @@ public: /// backtrace (if available) std::string getBacktrace() const; - const std::string header{"====== Exception thrown ======\n"}; - -protected: +private: std::string message; #if BOUT_USE_BACKTRACE static constexpr unsigned int TRACE_MAX = 128; - void* trace[TRACE_MAX]; + std::array trace{}; int trace_size; char** messages; #endif diff --git a/include/bout/build_config.hxx b/include/bout/build_config.hxx index a98c615c77..08158d00e9 100644 --- a/include/bout/build_config.hxx +++ b/include/bout/build_config.hxx @@ -17,6 +17,7 @@ constexpr auto has_gettext = static_cast(BOUT_HAS_GETTEXT); constexpr auto has_lapack = static_cast(BOUT_HAS_LAPACK); constexpr auto has_legacy_netcdf = static_cast(BOUT_HAS_LEGACY_NETCDF); constexpr auto has_netcdf = static_cast(BOUT_HAS_NETCDF); +constexpr auto has_adios2 = static_cast(BOUT_HAS_ADIOS2); constexpr auto has_petsc = static_cast(BOUT_HAS_PETSC); constexpr auto has_hypre = static_cast(BOUT_HAS_HYPRE); constexpr auto has_umpire = static_cast(BOUT_HAS_UMPIRE); diff --git a/include/bout/constants.hxx b/include/bout/constants.hxx index c811799aef..273ab2270e 100644 --- a/include/bout/constants.hxx +++ b/include/bout/constants.hxx @@ -3,8 +3,8 @@ * **************************************************************************/ -#ifndef __CONSTANTS_H__ -#define __CONSTANTS_H__ +#ifndef BOUT_CONSTANTS_H +#define BOUT_CONSTANTS_H #include @@ -28,4 +28,4 @@ constexpr BoutReal M_Deuterium = 2.01410178 * amu; ///< Mass of a Deuterium atom constexpr BoutReal M_Tritium = 3.0160492 * amu; ///< Mass of a Tritium atom } // namespace SI -#endif // __CONSTANTS_H__ +#endif // BOUT_CONSTANTS_H diff --git a/include/bout/coordinates.hxx b/include/bout/coordinates.hxx index 42efcad84c..49feffa0a7 100644 --- a/include/bout/coordinates.hxx +++ b/include/bout/coordinates.hxx @@ -30,8 +30,8 @@ * **************************************************************************/ -#ifndef __COORDINATES_H__ -#define __COORDINATES_H__ +#ifndef BOUT_COORDINATES_H +#define BOUT_COORDINATES_H #include "bout/field2d.hxx" #include "bout/field3d.hxx" @@ -262,4 +262,4 @@ private: }; */ -#endif // __COORDINATES_H__ +#endif // BOUT_COORDINATES_H diff --git a/include/bout/cyclic_reduction.hxx b/include/bout/cyclic_reduction.hxx index d4ef958e93..d4c0920910 100644 --- a/include/bout/cyclic_reduction.hxx +++ b/include/bout/cyclic_reduction.hxx @@ -38,8 +38,8 @@ * ************************************************************************/ -#ifndef __CYCLIC_REDUCE_H__ -#define __CYCLIC_REDUCE_H__ +#ifndef BOUT_CYCLIC_REDUCE_H +#define BOUT_CYCLIC_REDUCE_H #ifdef DIAGNOSE #undef DIAGNOSE @@ -101,7 +101,7 @@ public: Matrix bMatrix(1, N); Matrix cMatrix(1, N); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < N; ++i) { aMatrix(0, i) = a[i]; bMatrix(0, i) = b[i]; @@ -126,7 +126,7 @@ public: allocMemory(nprocs, nsys, N); // Fill coefficient array - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int j = 0; j < Nsys; j++) { for (int i = 0; i < N; i++) { coefs(j, 4 * i) = a(j, i); @@ -149,7 +149,7 @@ public: Matrix xMatrix(1, N); // Copy input data into matrix - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < N; ++i) { rhsMatrix(0, i) = rhs[i]; } @@ -158,7 +158,7 @@ public: solve(rhsMatrix, xMatrix); // Copy result back into argument - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < N; ++i) { x[i] = xMatrix(0, i); } @@ -184,7 +184,7 @@ public: // Insert RHS into coefs array. Ordered to allow efficient partitioning // for MPI send/receives - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int j = 0; j < Nsys; j++) { for (int i = 0; i < N; i++) { coefs(j, 4 * i + 3) = rhs(j, i); @@ -230,7 +230,7 @@ public: if (p == myproc) { // Just copy the data - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < myns; i++) { for (int j = 0; j < 8; j++) { ifcs(i, 8 * p + j) = myif(sys0 + i, j); @@ -285,7 +285,7 @@ public: #ifdef DIAGNOSE output << "Copying received data from " << p << endl; #endif - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < myns; i++) { for (int j = 0; j < 8; j++) { #ifdef DIAGNOSE @@ -317,7 +317,7 @@ public: x1.ensureUnique(); xn.ensureUnique(); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < myns; ++i) { // (a b) (x1) = (b1) // (c d) (xn) (bn) @@ -364,7 +364,7 @@ public: if (p == myproc) { // Just copy the data - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < myns; i++) { x1[sys0 + i] = ifx(i, 2 * p); xn[sys0 + i] = ifx(i, 2 * p + 1); @@ -389,7 +389,7 @@ public: // Send data for (int p = 0; p < nprocs; p++) { // Loop over processor if (p != myproc) { - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < myns; i++) { ifp[2 * i] = ifx(i, 2 * p); ifp[2 * i + 1] = ifx(i, 2 * p + 1); @@ -427,7 +427,7 @@ public: nsp++; } - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nsp; i++) { x1[s0 + i] = recvbuffer(fromproc, 2 * i); xn[s0 + i] = recvbuffer(fromproc, 2 * i + 1); @@ -540,7 +540,7 @@ private: } #endif - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int j = 0; j < ns; j++) { // Calculate upper interface equation @@ -619,7 +619,7 @@ private: // Tridiagonal system, solve using serial Thomas algorithm // xa -- Result for each system // co -- Coefficients & rhs for each system - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < ns; i++) { // Loop over systems Array gam(nloc); // Thread-local array T bet = 1.0; @@ -640,4 +640,4 @@ private: } }; -#endif // __CYCLIC_REDUCE_H__ +#endif // BOUT_CYCLIC_REDUCE_H diff --git a/include/bout/dcomplex.hxx b/include/bout/dcomplex.hxx index 569b5f2c13..75bc9d26ff 100644 --- a/include/bout/dcomplex.hxx +++ b/include/bout/dcomplex.hxx @@ -29,8 +29,8 @@ * along with BOUT++. If not, see . * */ -#ifndef __DCOMPLEX_H__ -#define __DCOMPLEX_H__ +#ifndef BOUT_DCOMPLEX_H +#define BOUT_DCOMPLEX_H #include "bout/bout_types.hxx" #include @@ -44,4 +44,4 @@ struct fcmplx { BoutReal r, i; }; -#endif // __DCOMPLEX_H__ +#endif // BOUT_DCOMPLEX_H diff --git a/include/bout/derivs.hxx b/include/bout/derivs.hxx index c01e1562fc..1c360bb9cd 100644 --- a/include/bout/derivs.hxx +++ b/include/bout/derivs.hxx @@ -26,8 +26,8 @@ * **************************************************************************/ -#ifndef __DERIVS_H__ -#define __DERIVS_H__ +#ifndef BOUT_DERIVS_H +#define BOUT_DERIVS_H #include "bout/field2d.hxx" #include "bout/field3d.hxx" @@ -701,4 +701,4 @@ Coordinates::FieldMetric D2DYDZ(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT const std::string& method = "DEFAULT", const std::string& region = "RGN_NOBNDRY"); -#endif // __DERIVS_H__ +#endif // BOUT_DERIVS_H diff --git a/include/bout/difops.hxx b/include/bout/difops.hxx index 2b5c6746fd..71053d454a 100644 --- a/include/bout/difops.hxx +++ b/include/bout/difops.hxx @@ -33,8 +33,8 @@ * *******************************************************************************/ -#ifndef __DIFOPS_H__ -#define __DIFOPS_H__ +#ifndef BOUT_DIFOPS_H +#define BOUT_DIFOPS_H #include "bout/field2d.hxx" #include "bout/field3d.hxx" @@ -310,4 +310,4 @@ Field3D bracket(const Field3D& f, const Field2D& g, BRACKET_METHOD method = BRAC Field3D bracket(const Field3D& f, const Field3D& g, BRACKET_METHOD method = BRACKET_STD, CELL_LOC outloc = CELL_DEFAULT, Solver* solver = nullptr); -#endif /* __DIFOPS_H__ */ +#endif /* BOUT_DIFOPS_H */ diff --git a/include/bout/expr.hxx b/include/bout/expr.hxx index e03c07aa49..267af202ed 100644 --- a/include/bout/expr.hxx +++ b/include/bout/expr.hxx @@ -9,8 +9,8 @@ * **************************************************************************/ -#ifndef __EXPR_H__ -#define __EXPR_H__ +#ifndef BOUT_EXPR_H +#define BOUT_EXPR_H #warning expr.hxx is deprecated. Do not use! @@ -205,4 +205,4 @@ const Field3D eval3D(Expr e) { return result; } -#endif // __EXPR_H__ +#endif // BOUT_EXPR_H diff --git a/include/bout/fft.hxx b/include/bout/fft.hxx index 8e74321f2a..fdec8b7bec 100644 --- a/include/bout/fft.hxx +++ b/include/bout/fft.hxx @@ -25,8 +25,8 @@ * *******************************************************************************/ -#ifndef __FFT_H__ -#define __FFT_H__ +#ifndef BOUT_FFT_H +#define BOUT_FFT_H #include "bout/dcomplex.hxx" #include @@ -132,4 +132,4 @@ inline void DST_rev(dcomplex* in, int length, BoutReal* out) { return bout::fft::DST_rev(in, length, out); } -#endif // __FFT_H__ +#endif // BOUT_FFT_H diff --git a/include/bout/field.hxx b/include/bout/field.hxx index be347f60d0..c0693ec0fb 100644 --- a/include/bout/field.hxx +++ b/include/bout/field.hxx @@ -122,6 +122,9 @@ public: */ virtual int getNz() const; + /// Get the total number of points + virtual int size() const = 0; + friend void swap(Field& first, Field& second) noexcept { using std::swap; swap(static_cast(first), static_cast(second)); @@ -179,7 +182,7 @@ inline bool areFieldsCompatible(const Field& field1, const Field& field2) { /// copied and a data array that is allocated but not initialised. template inline T emptyFrom(const T& f) { - static_assert(bout::utils::is_Field::value, "emptyFrom only works on Fields"); + static_assert(bout::utils::is_Field_v, "emptyFrom only works on Fields"); return T(f.getMesh(), f.getLocation(), {f.getDirectionY(), f.getDirectionZ()}) .allocate(); } @@ -188,7 +191,7 @@ inline T emptyFrom(const T& f) { /// another field and a data array allocated and initialised to zero. template inline T zeroFrom(const T& f) { - static_assert(bout::utils::is_Field::value, "zeroFrom only works on Fields"); + static_assert(bout::utils::is_Field_v, "zeroFrom only works on Fields"); T result{emptyFrom(f)}; result = 0.; return result; @@ -198,7 +201,7 @@ inline T zeroFrom(const T& f) { /// another field and a data array allocated and filled with the given value. template inline T filledFrom(const T& f, BoutReal fill_value) { - static_assert(bout::utils::is_Field::value, "filledFrom only works on Fields"); + static_assert(bout::utils::is_Field_v, "filledFrom only works on Fields"); T result{emptyFrom(f)}; result = fill_value; return result; @@ -217,7 +220,7 @@ template < typename T, typename Function, typename = decltype(std::declval()(std::declval()))> inline T filledFrom(const T& f, Function func, std::string region_string = "RGN_ALL") { - static_assert(bout::utils::is_Field::value, "filledFrom only works on Fields"); + static_assert(bout::utils::is_Field_v, "filledFrom only works on Fields"); T result{emptyFrom(f)}; BOUT_FOR(i, result.getRegion(region_string)) { result[i] = func(i); } return result; @@ -286,14 +289,14 @@ inline void checkPositive(const T& f, const std::string& name = "field", /// Convert \p f to field-aligned space in \p region (default: whole domain) template inline T toFieldAligned(const T& f, const std::string& region = "RGN_ALL") { - static_assert(bout::utils::is_Field::value, "toFieldAligned only works on Fields"); + static_assert(bout::utils::is_Field_v, "toFieldAligned only works on Fields"); return f.getCoordinates()->getParallelTransform().toFieldAligned(f, region); } /// Convert \p f from field-aligned space in \p region (default: whole domain) template inline T fromFieldAligned(const T& f, const std::string& region = "RGN_ALL") { - static_assert(bout::utils::is_Field::value, "fromFieldAligned only works on Fields"); + static_assert(bout::utils::is_Field_v, "fromFieldAligned only works on Fields"); return f.getCoordinates()->getParallelTransform().fromFieldAligned(f, region); } @@ -367,7 +370,7 @@ inline bool isUniform(const T& f, bool allpe = false, /// @param[in] allpe Check over all processors /// @param[in] region The region to assume is uniform template > -inline BoutReal getUniform(const T& f, MAYBE_UNUSED(bool allpe) = false, +inline BoutReal getUniform(const T& f, [[maybe_unused]] bool allpe = false, const std::string& region = "RGN_ALL") { #if CHECK > 1 if (not isUniform(f, allpe, region)) { diff --git a/include/bout/field2d.hxx b/include/bout/field2d.hxx index 1c1169a175..10b801ef8d 100644 --- a/include/bout/field2d.hxx +++ b/include/bout/field2d.hxx @@ -27,13 +27,13 @@ class Field2D; #pragma once -#ifndef __FIELD2D_H__ -#define __FIELD2D_H__ +#ifndef BOUT_FIELD2D_H +#define BOUT_FIELD2D_H class Mesh; #include "bout/field.hxx" #include "bout/field_data.hxx" -class Field3D; //#include "bout/field3d.hxx" +class Field3D; #include "bout/fieldperp.hxx" #include "bout/stencils.hxx" @@ -174,6 +174,9 @@ public: /// Return a Region reference to use to iterate over this field const Region& getRegion(REGION region) const; const Region& getRegion(const std::string& region_name) const; + const Region& getValidRegionWithDefault(const std::string& region_name) const { + return getRegion(region_name); + } Region::RegionIndices::const_iterator begin() const { return std::begin(getRegion("RGN_ALL")); @@ -277,10 +280,12 @@ public: friend void swap(Field2D& first, Field2D& second) noexcept; + int size() const override { return nx * ny; }; + +private: /// Internal data array. Handles allocation/freeing of memory Array data; -private: /// Array sizes (from fieldmesh). These are valid only if fieldmesh is not null int nx{-1}, ny{-1}; @@ -369,4 +374,4 @@ bool operator==(const Field2D& a, const Field2D& b); std::ostream& operator<<(std::ostream& out, const Field2D& value); -#endif /* __FIELD2D_H__ */ +#endif /* BOUT_FIELD2D_H */ diff --git a/include/bout/field3d.hxx b/include/bout/field3d.hxx index 8213742248..ba8c8e879e 100644 --- a/include/bout/field3d.hxx +++ b/include/bout/field3d.hxx @@ -23,8 +23,8 @@ class Field3D; #pragma once -#ifndef __FIELD3D_H__ -#define __FIELD3D_H__ +#ifndef BOUT_FIELD3D_H +#define BOUT_FIELD3D_H class Mesh; // #include "bout/mesh.hxx" #include "bout/bout_types.hxx" @@ -40,6 +40,7 @@ class Mesh; // #include "bout/mesh.hxx" #include "bout/utils.hxx" +#include #include /// Class for 3D X-Y-Z scalar fields @@ -313,6 +314,13 @@ public: /// const Region& getRegion(REGION region) const; const Region& getRegion(const std::string& region_name) const; + /// Use region provided by the default, and if none is set, use the provided one + const Region& getValidRegionWithDefault(const std::string& region_name) const; + void setRegion(const std::string& region_name); + void resetRegion() { regionID.reset(); }; + void setRegion(size_t id) { regionID = id; }; + void setRegion(std::optional id) { regionID = id; }; + std::optional getRegionID() const { return regionID; }; /// Return a Region reference to use to iterate over the x- and /// y-indices of this field @@ -489,6 +497,8 @@ public: friend void swap(Field3D& first, Field3D& second) noexcept; + int size() const override { return nx * ny * nz; }; + private: /// Array sizes (from fieldmesh). These are valid only if fieldmesh is not null int nx{-1}, ny{-1}, nz{-1}; @@ -501,6 +511,9 @@ private: /// Fields containing values along Y std::vector yup_fields{}, ydown_fields{}; + + /// RegionID over which the field is valid + std::optional regionID; }; // Non-member overloaded operators @@ -643,4 +656,4 @@ bool operator==(const Field3D& a, const Field3D& b); /// Output a string describing a Field3D to a stream std::ostream& operator<<(std::ostream& out, const Field3D& value); -#endif /* __FIELD3D_H__ */ +#endif /* BOUT_FIELD3D_H */ diff --git a/include/bout/field_accessor.hxx b/include/bout/field_accessor.hxx index 16661a0e75..69b58da979 100644 --- a/include/bout/field_accessor.hxx +++ b/include/bout/field_accessor.hxx @@ -39,9 +39,9 @@ struct BoutRealArray { /// Cast operators, so can be assigned to a raw pointer /// Note: Not explicit, so can be cast implicitly - operator BoutReal*() { return data; } + BOUT_HOST_DEVICE operator BoutReal*() { return data; } - operator const BoutReal*() const { return data; } + BOUT_HOST_DEVICE operator const BoutReal*() const { return data; } }; /// Thin wrapper around field data, for fast but unsafe access diff --git a/include/bout/field_data.hxx b/include/bout/field_data.hxx index 59bd751fc4..185dcabf2d 100644 --- a/include/bout/field_data.hxx +++ b/include/bout/field_data.hxx @@ -38,15 +38,14 @@ class FieldData; #include #include -// Including the next line leads to compiler errors -//#include "bout/boundary_op.hxx" class BoundaryOp; class BoundaryOpPar; class Coordinates; class Mesh; #include "bout/boundary_region.hxx" -#include "bout/parallel_boundary_region.hxx" +class BoundaryRegionPar; +enum class BndryLoc; #include "bout/sys/expressionparser.hxx" diff --git a/include/bout/field_factory.hxx b/include/bout/field_factory.hxx index ee228d836c..2a20226b2e 100644 --- a/include/bout/field_factory.hxx +++ b/include/bout/field_factory.hxx @@ -26,8 +26,8 @@ class FieldFactory; -#ifndef __FIELD_FACTORY_H__ -#define __FIELD_FACTORY_H__ +#ifndef BOUT_FIELD_FACTORY_H +#define BOUT_FIELD_FACTORY_H #include "bout/mesh.hxx" @@ -165,4 +165,4 @@ public: } }; -#endif // __FIELD_FACTORY_H__ +#endif // BOUT_FIELD_FACTORY_H diff --git a/include/bout/fieldgroup.hxx b/include/bout/fieldgroup.hxx index c33bd63e16..184766c6b8 100644 --- a/include/bout/fieldgroup.hxx +++ b/include/bout/fieldgroup.hxx @@ -1,5 +1,5 @@ -#ifndef __FIELDGROUP_H__ -#define __FIELDGROUP_H__ +#ifndef BOUT_FIELDGROUP_H +#define BOUT_FIELDGROUP_H #include "bout/field_data.hxx" #include @@ -190,4 +190,4 @@ private: /// Combine two FieldGroups FieldGroup operator+(const FieldGroup& lhs, const FieldGroup& rhs); -#endif // __FIELDGROUP_H__ +#endif // BOUT_FIELDGROUP_H diff --git a/include/bout/fieldperp.hxx b/include/bout/fieldperp.hxx index 4433463e8f..6995308dbe 100644 --- a/include/bout/fieldperp.hxx +++ b/include/bout/fieldperp.hxx @@ -25,8 +25,8 @@ class FieldPerp; -#ifndef __FIELDPERP_H__ -#define __FIELDPERP_H__ +#ifndef BOUT_FIELDPERP_H +#define BOUT_FIELDPERP_H #include "bout/field.hxx" @@ -98,6 +98,9 @@ public: /// Return a Region reference to use to iterate over this field const Region& getRegion(REGION region) const; const Region& getRegion(const std::string& region_name) const; + const Region& getValidRegionWithDefault(const std::string& region_name) const { + return getRegion(region_name); + } Region::RegionIndices::const_iterator begin() const { return std::begin(getRegion("RGN_ALL")); @@ -287,6 +290,8 @@ public: friend void swap(FieldPerp& first, FieldPerp& second) noexcept; + int size() const override { return nx * nz; }; + private: /// The Y index at which this FieldPerp is defined int yindex{-1}; diff --git a/include/bout/format.hxx b/include/bout/format.hxx deleted file mode 100644 index 846303a3fd..0000000000 --- a/include/bout/format.hxx +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __BOUT_FORMAT_H__ -#define __BOUT_FORMAT_H__ - -/// Tell GCC that a function has a printf-style like argument -/// The first argument is the position of format string, and the -/// second is the position of the first variadic argument -/// Note that it seems to start counting from 1, and also counts a -/// *this pointer, as the first argument, so often 2 would be the -/// first argument. -#if defined(__GNUC__) -#define BOUT_FORMAT_ARGS(i, j) __attribute__((format(printf, i, j))) -#else -#define BOUT_FORMAT_ARGS(i, j) -#endif - -#endif //__BOUT_FORMAT_H__ diff --git a/include/bout/fv_ops.hxx b/include/bout/fv_ops.hxx index 5f1e688bd8..94007a57a2 100644 --- a/include/bout/fv_ops.hxx +++ b/include/bout/fv_ops.hxx @@ -2,8 +2,8 @@ Finite-volume discretisation methods. Flux-conservative form */ -#ifndef __FV_OPS_H__ -#define __FV_OPS_H__ +#ifndef BOUT_FV_OPS_H +#define BOUT_FV_OPS_H #include "bout/field3d.hxx" #include "bout/globals.hxx" @@ -525,4 +525,4 @@ const Field3D Div_f_v(const Field3D& n_in, const Vector3D& v, bool bndry_flux) { */ Field3D Div_Perp_Lap(const Field3D& a, const Field3D& f, CELL_LOC outloc = CELL_DEFAULT); } // namespace FV -#endif // __FV_OPS_H__ +#endif // BOUT_FV_OPS_H diff --git a/include/bout/generic_factory.hxx b/include/bout/generic_factory.hxx index 3a2a63c94c..9493ef77f1 100644 --- a/include/bout/generic_factory.hxx +++ b/include/bout/generic_factory.hxx @@ -1,8 +1,8 @@ /// Base type for factories #pragma once -#ifndef __BOUT_GENERIC_FACTORY_H__ -#define __BOUT_GENERIC_FACTORY_H__ +#ifndef BOUT_GENERIC_FACTORY_H +#define BOUT_GENERIC_FACTORY_H #include "bout/boutexception.hxx" #include "bout/options.hxx" @@ -48,14 +48,6 @@ /// RegisterInFactory register("derived_type"); /// auto foo = MyFactory::getInstance().create("derived_type"); /// -/// In a .cxx file the static members should be declared: -/// -/// constexpr decltype(MyFactory::type_name) MyFactory::type_name; -/// constexpr decltype(MyFactory::section_name) MyFactory::section_name; -/// constexpr decltype(MyFactory::option_name) MyFactory::option_name; -/// constexpr decltype(MyFactory::default_type) MyFactory::default_type; -/// -/// /// @tparam BaseType The base class that this factory creates /// @tparam DerivedFactory The derived factory inheriting from this class /// @tparam TypeCreator The function signature for creating a new BaseType @@ -259,4 +251,4 @@ public: }; }; -#endif // __BOUT_GENERIC_FACTORY_H__ +#endif // BOUT_GENERIC_FACTORY_H diff --git a/include/bout/globalfield.hxx b/include/bout/globalfield.hxx index 85252f4962..038a0875bf 100644 --- a/include/bout/globalfield.hxx +++ b/include/bout/globalfield.hxx @@ -6,8 +6,8 @@ class GlobalField; class GlobalField2D; -#ifndef __GLOBALFIELD_H__ -#define __GLOBALFIELD_H__ +#ifndef BOUT_GLOBALFIELD_H +#define BOUT_GLOBALFIELD_H #include "mesh.hxx" @@ -257,4 +257,4 @@ private: bool data_valid; }; -#endif // __GLOBALFIELD_H__ +#endif // BOUT_GLOBALFIELD_H diff --git a/include/bout/globalindexer.hxx b/include/bout/globalindexer.hxx index a061f387dc..e756ead3b2 100644 --- a/include/bout/globalindexer.hxx +++ b/include/bout/globalindexer.hxx @@ -35,7 +35,7 @@ using InterpolationWeights = std::vector template class GlobalIndexer { public: - static_assert(bout::utils::is_Field::value, "GlobalIndexer only works with Fields"); + static_assert(bout::utils::is_Field_v, "GlobalIndexer only works with Fields"); using ind_type = typename T::ind_type; GlobalIndexer() = default; @@ -45,7 +45,8 @@ public: bool autoInitialise = true) : fieldmesh(localmesh), indices(-1., localmesh), stencils(std::move(stencil)) { - Region allCandidate, bndryCandidate; + Region allCandidate; + Region bndryCandidate; if (stencils.getNumParts() > 0) { std::set allIndices(getRegionNobndry().getIndices().begin(), getRegionNobndry().getIndices().end()); @@ -69,14 +70,14 @@ public: bndryCandidate = mask(allCandidate, getRegionNobndry()); - regionInnerX = getIntersection(bndryCandidate, indices.getRegion("RGN_INNER_X")); - regionOuterX = getIntersection(bndryCandidate, indices.getRegion("RGN_OUTER_X")); - if (std::is_same::value) { + regionInnerX = intersection(bndryCandidate, indices.getRegion("RGN_INNER_X")); + regionOuterX = intersection(bndryCandidate, indices.getRegion("RGN_OUTER_X")); + if constexpr (std::is_same_v) { regionLowerY = Region({}); regionUpperY = Region({}); } else { - regionLowerY = getIntersection(bndryCandidate, indices.getRegion("RGN_LOWER_Y")); - regionUpperY = getIntersection(bndryCandidate, indices.getRegion("RGN_UPPER_Y")); + regionLowerY = intersection(bndryCandidate, indices.getRegion("RGN_LOWER_Y")); + regionUpperY = intersection(bndryCandidate, indices.getRegion("RGN_UPPER_Y")); } regionBndry = regionLowerY + regionInnerX + regionOuterX + regionUpperY; regionAll = getRegionNobndry() + regionBndry; @@ -85,7 +86,7 @@ public: int localSize = size(); MPI_Comm comm = - std::is_same::value ? fieldmesh->getXcomm() : BoutComm::get(); + std::is_same_v ? fieldmesh->getXcomm() : BoutComm::get(); fieldmesh->getMpi().MPI_Scan(&localSize, &globalEnd, 1, MPI_INT, MPI_SUM, comm); globalEnd--; int counter = globalStart = globalEnd - size() + 1; @@ -105,7 +106,18 @@ public: /// Finish setting up the indexer, communicating indices across /// processes and, if possible, calculating the sparsity pattern of /// any matrices. - void initialise() { fieldmesh->communicate(indices); } + void initialise() { + // We need to ensure any _guard_ cells are -1 so we don't include them + int_indices.reallocate(indices.size()); + BOUT_FOR(index, indices.getRegion("RGN_GUARDS")) { int_indices[index.ind] = -1; } + // Now we can communicate to get global indices from neighbouring processes + fieldmesh->communicate(indices); + // Finally, we fill in the global indices including in the + // _boundaries_ (*not* guards) + BOUT_FOR(index, regionAll) { + int_indices[index.ind] = static_cast(indices[index]); + } + } Mesh* getMesh() const { return fieldmesh; } @@ -157,6 +169,8 @@ public: int size() const { return regionAll.size(); } + const Array& getIntIndices() const { return int_indices; } + protected: // Must not be const as the index field needs to be mutable in order // to fake parallel communication in the unit tests. @@ -206,6 +220,8 @@ private: /// Fields containing the indices for each element (as reals) T indices; + /// Indices as integers + Array int_indices; /// The first and last global index on this processor (inclusive in /// both cases) int globalStart, globalEnd; diff --git a/include/bout/globals.hxx b/include/bout/globals.hxx index ae7edff298..64b3a09ee3 100644 --- a/include/bout/globals.hxx +++ b/include/bout/globals.hxx @@ -24,8 +24,8 @@ * **************************************************************************/ -#ifndef __GLOBALS_H__ -#define __GLOBALS_H__ +#ifndef BOUT_GLOBALS_H +#define BOUT_GLOBALS_H #include "bout/macro_for_each.hxx" @@ -97,4 +97,4 @@ SETTING(MpiWrapper* mpi, nullptr); ///< The MPI wrapper object } // namespace globals } // namespace bout -#endif // __GLOBALS_H__ +#endif // BOUT_GLOBALS_H diff --git a/include/bout/griddata.hxx b/include/bout/griddata.hxx index 875cb07d7a..29a32e5779 100644 --- a/include/bout/griddata.hxx +++ b/include/bout/griddata.hxx @@ -25,8 +25,8 @@ class GridDataSource; -#ifndef __GRIDDATA_H__ -#define __GRIDDATA_H__ +#ifndef BOUT_GRIDDATA_H +#define BOUT_GRIDDATA_H #include "mesh.hxx" #include "bout/bout_types.hxx" @@ -299,4 +299,4 @@ private: Options* options; }; -#endif // __GRIDDATA_H__ +#endif // BOUT_GRIDDATA_H diff --git a/include/bout/gyro_average.hxx b/include/bout/gyro_average.hxx index 0f9f2a13f7..63ef13279b 100644 --- a/include/bout/gyro_average.hxx +++ b/include/bout/gyro_average.hxx @@ -29,8 +29,8 @@ * **************************************************************/ -#ifndef __GYRO_AVERAGE_H__ -#define __GYRO_AVERAGE_H__ +#ifndef BOUT_GYRO_AVERAGE_H +#define BOUT_GYRO_AVERAGE_H #include "bout/field3d.hxx" #include "bout/invert_laplace.hxx" @@ -115,4 +115,4 @@ Field3D gyroPade2(const Field3D& f, const Field2D& rho, Field3D gyroPade2(const Field3D& f, BoutReal rho, int inner_boundary_flags = GYRO_FLAGS, int outer_boundary_flags = GYRO_FLAGS); -#endif // __GYRO_AVERAGE_H__ +#endif // BOUT_GYRO_AVERAGE_H diff --git a/include/bout/hypre_interface.hxx b/include/bout/hypre_interface.hxx index 2bbdfdae63..cd3af7d39c 100644 --- a/include/bout/hypre_interface.hxx +++ b/include/bout/hypre_interface.hxx @@ -73,7 +73,7 @@ class HypreVector { HypreLib hyprelib{}; public: - static_assert(bout::utils::is_Field::value, "HypreVector only works with Fields"); + static_assert(bout::utils::is_Field_v, "HypreVector only works with Fields"); using ind_type = typename T::ind_type; HypreVector() = default; @@ -138,7 +138,7 @@ public: : indexConverter(indConverter) { ASSERT1(indConverter->getMesh() == f.getMesh()); const MPI_Comm comm = - std::is_same::value ? f.getMesh()->getXcomm() : BoutComm::get(); + std::is_same_v ? f.getMesh()->getXcomm() : BoutComm::get(); HYPRE_BigInt jlower = indConverter->getGlobalStart(); HYPRE_BigInt jupper = jlower + indConverter->size() - 1; // inclusive end @@ -159,7 +159,7 @@ public: explicit HypreVector(IndexerPtr indConverter) : indexConverter(indConverter) { Mesh& mesh = *indConverter->getMesh(); const MPI_Comm comm = - std::is_same::value ? mesh.getXcomm() : BoutComm::get(); + std::is_same_v ? mesh.getXcomm() : BoutComm::get(); HYPRE_BigInt jlower = indConverter->getGlobalStart(); HYPRE_BigInt jupper = jlower + indConverter->size() - 1; // inclusive end @@ -338,7 +338,7 @@ class HypreMatrix { }; public: - static_assert(bout::utils::is_Field::value, "HypreMatrix only works with Fields"); + static_assert(bout::utils::is_Field_v, "HypreMatrix only works with Fields"); using ind_type = typename T::ind_type; HypreMatrix() = default; @@ -380,7 +380,7 @@ public: : hypre_matrix(new HYPRE_IJMatrix, MatrixDeleter{}), index_converter(indConverter) { Mesh* mesh = indConverter->getMesh(); const MPI_Comm comm = - std::is_same::value ? mesh->getXcomm() : BoutComm::get(); + std::is_same_v ? mesh->getXcomm() : BoutComm::get(); parallel_transform = &mesh->getCoordinates()->getParallelTransform(); ilower = indConverter->getGlobalStart(); @@ -480,7 +480,7 @@ public: weights.begin(), weights.end(), std::back_inserter(values), [&value_](BoutReal weight) -> HYPRE_Complex { return weight * value_; }); const HYPRE_BigInt ncolumns = static_cast(positions.size()); - // BOUT_OMP(critical) + // BOUT_OMP_SAFE(critical) for (HYPRE_BigInt i = 0; i < ncolumns; ++i) { matrix->setVal(row, positions[i], values[i]); } @@ -495,7 +495,7 @@ public: weights.begin(), weights.end(), std::back_inserter(values), [&value_](BoutReal weight) -> HYPRE_Complex { return weight * value_; }); const HYPRE_BigInt ncolumns = static_cast(positions.size()); - // BOUT_OMP(critical) + // BOUT_OMP_SAFE(critical) for (HYPRE_BigInt i = 0; i < ncolumns; ++i) { matrix->addVal(row, positions[i], values[i]); } @@ -651,9 +651,8 @@ public: }(); const int ny = - std::is_same::value ? 1 : index_converter->getMesh()->LocalNy; - const int nz = - std::is_same::value ? 1 : index_converter->getMesh()->LocalNz; + std::is_same_v ? 1 : index_converter->getMesh()->LocalNy; + const int nz = std::is_same_v ? 1 : index_converter->getMesh()->LocalNz; std::transform( pw.begin(), pw.end(), std::back_inserter(positions), [this, ny, nz](ParallelTransform::PositionsAndWeights p) -> HYPRE_Int { @@ -714,7 +713,7 @@ public: HypreMatrix yup(int index = 0) { return ynext(index + 1); } HypreMatrix ydown(int index = 0) { return ynext(-index - 1); } HypreMatrix ynext(int dir) { - if (std::is_same::value and ((yoffset + dir) != 0)) { + if (std::is_same_v and ((yoffset + dir) != 0)) { throw BoutException("Can not get ynext for FieldPerp"); } HypreMatrix result; @@ -726,7 +725,7 @@ public: result.index_converter = index_converter; result.location = location; result.initialised = initialised; - result.yoffset = std::is_same::value ? 0 : yoffset + dir; + result.yoffset = std::is_same_v ? 0 : yoffset + dir; result.parallel_transform = parallel_transform; result.assembled = assembled; result.num_rows = num_rows; @@ -804,7 +803,7 @@ public: "values are: gmres, bicgstab, pcg") .withDefault(HYPRE_SOLVER_TYPE::bicgstab); - comm = std::is_same::value ? mesh.getXcomm() : BoutComm::get(); + comm = std::is_same_v ? mesh.getXcomm() : BoutComm::get(); auto print_level = options["hypre_print_level"] diff --git a/include/bout/index_derivs.hxx b/include/bout/index_derivs.hxx index 8cb5c88aff..456f98f8c2 100644 --- a/include/bout/index_derivs.hxx +++ b/include/bout/index_derivs.hxx @@ -124,13 +124,6 @@ public: BoutReal apply(const stencil& v, const stencil& f) const { return func(v, f); } }; -// Redundant definitions because C++ -// Not necessary in C++17 -template -constexpr FF DerivativeType::func; -template -constexpr metaData DerivativeType::meta; - ///////////////////////////////////////////////////////////////////////////////// /// Following code is for dealing with registering a method/methods for all /// template combinations, in conjunction with the template_combinations code. diff --git a/include/bout/index_derivs_interface.hxx b/include/bout/index_derivs_interface.hxx index 1f6e8bfbe9..8f7e41a68e 100644 --- a/include/bout/index_derivs_interface.hxx +++ b/include/bout/index_derivs_interface.hxx @@ -48,7 +48,7 @@ T flowDerivative(const T& vel, const T& f, CELL_LOC outloc, const std::string& m AUTO_TRACE(); // Checks - static_assert(bout::utils::is_Field2D::value || bout::utils::is_Field3D::value, + static_assert(bout::utils::is_Field2D_v || bout::utils::is_Field3D_v, "flowDerivative only works on Field2D or Field3D input"); static_assert(derivType == DERIV::Upwind || derivType == DERIV::Flux, @@ -113,7 +113,7 @@ T standardDerivative(const T& f, CELL_LOC outloc, const std::string& method, AUTO_TRACE(); // Checks - static_assert(bout::utils::is_Field2D::value || bout::utils::is_Field3D::value, + static_assert(bout::utils::is_Field2D_v || bout::utils::is_Field3D_v, "standardDerivative only works on Field2D or Field3D input"); static_assert(derivType == DERIV::Standard || derivType == DERIV::StandardSecond diff --git a/include/bout/initialprofiles.hxx b/include/bout/initialprofiles.hxx index 71cab22431..a2fc050b15 100644 --- a/include/bout/initialprofiles.hxx +++ b/include/bout/initialprofiles.hxx @@ -23,8 +23,8 @@ * **************************************************************************/ -#ifndef __INITIALPROF_H__ -#define __INITIALPROF_H__ +#ifndef BOUT_INITIALPROF_H +#define BOUT_INITIALPROF_H #include @@ -113,4 +113,4 @@ void initial_profile(const std::string& name, Vector2D& var); */ void initial_profile(const std::string& name, Vector3D& var); -#endif // __INITIALPROF_H__ +#endif // BOUT_INITIALPROF_H diff --git a/include/bout/interpolation.hxx b/include/bout/interpolation.hxx index 71fbd19e90..1f4b0a51b5 100644 --- a/include/bout/interpolation.hxx +++ b/include/bout/interpolation.hxx @@ -23,8 +23,8 @@ * **************************************************************************/ -#ifndef __INTERP_H__ -#define __INTERP_H__ +#ifndef BOUT_INTERP_H +#define BOUT_INTERP_H #include "bout/mesh.hxx" @@ -56,7 +56,7 @@ inline BoutReal interp(const stencil& s) { template const T interp_to(const T& var, CELL_LOC loc, const std::string region = "RGN_ALL") { AUTO_TRACE(); - static_assert(bout::utils::is_Field2D::value || bout::utils::is_Field3D::value, + static_assert(bout::utils::is_Field2D_v || bout::utils::is_Field3D_v, "interp_to must be templated with one of Field2D or Field3D."); ASSERT1(loc != CELL_DEFAULT); // doesn't make sense to interplote to CELL_DEFAULT @@ -121,12 +121,12 @@ const T interp_to(const T& var, CELL_LOC loc, const std::string region = "RGN_AL // We can't interpolate in y unless we're field-aligned // Field2D doesn't need to shift to/from field-aligned because it is axisymmetric, // so always set is_unaligned=false for Field2D. - const bool is_unaligned = std::is_same::value + const bool is_unaligned = std::is_same_v ? false : (var.getDirectionY() == YDirectionType::Standard); const T var_fa = is_unaligned ? toFieldAligned(var, "RGN_NOX") : var; - if (not std::is_base_of::value) { + if constexpr (not std::is_base_of_v) { // Field2D is axisymmetric, so YDirectionType::Standard and // YDirectionType::Aligned are equivalent, but trying to set // YDirectionType::Aligned explicitly is an error @@ -202,4 +202,4 @@ const T interp_to(const T& var, CELL_LOC loc, const std::string region = "RGN_AL return result; } -#endif // __INTERP_H__ +#endif // BOUT_INTERP_H diff --git a/include/bout/interpolation_xz.hxx b/include/bout/interpolation_xz.hxx index b3e8ba04ca..52dc38f174 100644 --- a/include/bout/interpolation_xz.hxx +++ b/include/bout/interpolation_xz.hxx @@ -21,8 +21,8 @@ * **************************************************************************/ -#ifndef __INTERP_XZ_H__ -#define __INTERP_XZ_H__ +#ifndef BOUT_INTERP_XZ_H +#define BOUT_INTERP_XZ_H #include "bout/mask.hxx" @@ -37,23 +37,64 @@ const Field3D interpolate(const Field2D& f, const Field3D& delta_x, const Field3D interpolate(const Field2D& f, const Field3D& delta_x); class XZInterpolation { +public: + int y_offset; + protected: Mesh* localmesh{nullptr}; - // 3D vector of points to skip (true -> skip this point) - BoutMask skip_mask; + std::string region_name; + std::shared_ptr> region{nullptr}; public: XZInterpolation(int y_offset = 0, Mesh* localmeshIn = nullptr) - : localmesh(localmeshIn == nullptr ? bout::globals::mesh : localmeshIn), - skip_mask(*localmesh, false), y_offset(y_offset) {} + : y_offset(y_offset), + localmesh(localmeshIn == nullptr ? bout::globals::mesh : localmeshIn) {} XZInterpolation(const BoutMask& mask, int y_offset = 0, Mesh* mesh = nullptr) : XZInterpolation(y_offset, mesh) { - skip_mask = mask; + region = regionFromMask(mask, localmesh); } + XZInterpolation(const std::string& region_name, int y_offset = 0, Mesh* mesh = nullptr) + : y_offset(y_offset), localmesh(mesh), region_name(region_name) {} + XZInterpolation(std::shared_ptr> region, int y_offset = 0, + Mesh* mesh = nullptr) + : y_offset(y_offset), localmesh(mesh), region(std::move(region)) {} virtual ~XZInterpolation() = default; - void setMask(const BoutMask& mask) { skip_mask = mask; } + void setMask(const BoutMask& mask) { + region = regionFromMask(mask, localmesh); + region_name = ""; + } + void setRegion(const std::string& region_name) { + this->region_name = region_name; + this->region = nullptr; + } + void setRegion(const std::shared_ptr>& region) { + this->region_name = ""; + this->region = region; + } + void setRegion(const Region& region) { + this->region_name = ""; + this->region = std::make_shared>(region); + } + Region getRegion() const { + if (!region_name.empty()) { + return localmesh->getRegion(region_name); + } + ASSERT1(region != nullptr); + return *region; + } + Region getRegion(const std::string& region) const { + const bool has_region = !region_name.empty() or this->region != nullptr; + if (!region.empty() and region != "RGN_ALL") { + if (has_region) { + return intersection(localmesh->getRegion(region), getRegion()); + } + return localmesh->getRegion(region); + } + ASSERT1(has_region); + return getRegion(); + } virtual void calcWeights(const Field3D& delta_x, const Field3D& delta_z, const std::string& region = "RGN_NOBNDRY") = 0; virtual void calcWeights(const Field3D& delta_x, const Field3D& delta_z, @@ -70,7 +111,6 @@ public: const std::string& region = "RGN_NOBNDRY") = 0; // Interpolate using the field at (x,y+y_offset,z), rather than (x,y,z) - int y_offset; void setYOffset(int offset) { y_offset = offset; } virtual std::vector @@ -117,7 +157,7 @@ public: XZHermiteSpline(int y_offset = 0, Mesh* mesh = nullptr); XZHermiteSpline(const BoutMask& mask, int y_offset = 0, Mesh* mesh = nullptr) : XZHermiteSpline(y_offset, mesh) { - skip_mask = mask; + region = regionFromMask(mask, localmesh); } void calcWeights(const Field3D& delta_x, const Field3D& delta_z, @@ -173,7 +213,7 @@ public: XZLagrange4pt(int y_offset = 0, Mesh* mesh = nullptr); XZLagrange4pt(const BoutMask& mask, int y_offset = 0, Mesh* mesh = nullptr) : XZLagrange4pt(y_offset, mesh) { - skip_mask = mask; + region = regionFromMask(mask, localmesh); } void calcWeights(const Field3D& delta_x, const Field3D& delta_z, @@ -206,7 +246,7 @@ public: XZBilinear(int y_offset = 0, Mesh* mesh = nullptr); XZBilinear(const BoutMask& mask, int y_offset = 0, Mesh* mesh = nullptr) : XZBilinear(y_offset, mesh) { - skip_mask = mask; + region = regionFromMask(mask, localmesh); } void calcWeights(const Field3D& delta_x, const Field3D& delta_z, @@ -236,7 +276,7 @@ public: ReturnType create(Options* options = nullptr, Mesh* mesh = nullptr) const { return Factory::create(getType(options), mesh); } - ReturnType create(const std::string& type, MAYBE_UNUSED(Options* options)) const { + ReturnType create(const std::string& type, [[maybe_unused]] Options* options) const { return Factory::create(type, nullptr); } @@ -246,4 +286,4 @@ public: template using RegisterXZInterpolation = XZInterpolationFactory::RegisterInFactory; -#endif // __INTERP_XZ_H__ +#endif // BOUT_INTERP_XZ_H diff --git a/include/bout/interpolation_z.hxx b/include/bout/interpolation_z.hxx index 596b2634fb..68cf5b0b06 100644 --- a/include/bout/interpolation_z.hxx +++ b/include/bout/interpolation_z.hxx @@ -20,8 +20,8 @@ * **************************************************************************/ -#ifndef __INTERP_Z_H__ -#define __INTERP_Z_H__ +#ifndef BOUT_INTERP_Z_H +#define BOUT_INTERP_Z_H #include "bout/generic_factory.hxx" #include "bout/paralleltransform.hxx" @@ -82,7 +82,7 @@ public: Region region_in = {}) const { return Factory::create(getType(nullptr), y_offset, mesh, region_in); } - ReturnType create(const std::string& type, MAYBE_UNUSED(Options* options)) const { + ReturnType create(const std::string& type, [[maybe_unused]] Options* options) const { return Factory::create(type, 0, nullptr, Region{}); } @@ -125,4 +125,4 @@ private: Field3D h11; }; -#endif // __INTERP_Z_H__ +#endif // BOUT_INTERP_Z_H diff --git a/include/bout/invert/laplacexy.hxx b/include/bout/invert/laplacexy.hxx index c07db58478..19da48dd4d 100644 --- a/include/bout/invert/laplacexy.hxx +++ b/include/bout/invert/laplacexy.hxx @@ -30,8 +30,8 @@ * **************************************************************************/ -#ifndef __LAPLACE_XY_H__ -#define __LAPLACE_XY_H__ +#ifndef BOUT_LAPLACE_XY_H +#define BOUT_LAPLACE_XY_H #include "bout/build_config.hxx" @@ -222,4 +222,4 @@ private: }; #endif // BOUT_HAS_PETSC -#endif // __LAPLACE_XY_H__ +#endif // BOUT_LAPLACE_XY_H diff --git a/include/bout/invert/laplacexy2.hxx b/include/bout/invert/laplacexy2.hxx index 6945de7b99..51f75f467d 100644 --- a/include/bout/invert/laplacexy2.hxx +++ b/include/bout/invert/laplacexy2.hxx @@ -30,8 +30,8 @@ * **************************************************************************/ -#ifndef __LAPLACE_XY2_H__ -#define __LAPLACE_XY2_H__ +#ifndef BOUT_LAPLACE_XY2_H +#define BOUT_LAPLACE_XY2_H #include "bout/build_defines.hxx" @@ -141,4 +141,4 @@ private: }; #endif // BOUT_HAS_PETSC -#endif // __LAPLACE_XY_H__ +#endif // BOUT_LAPLACE_XY2_H diff --git a/include/bout/invert/laplacexz.hxx b/include/bout/invert/laplacexz.hxx index 1b1ebef832..11f1c69330 100644 --- a/include/bout/invert/laplacexz.hxx +++ b/include/bout/invert/laplacexz.hxx @@ -28,8 +28,8 @@ * **************************************************************************/ -#ifndef __LAPLACEXZ_H__ -#define __LAPLACEXZ_H__ +#ifndef BOUT_LAPLACEXZ_H +#define BOUT_LAPLACEXZ_H #include #include @@ -91,4 +91,4 @@ protected: private: }; -#endif // __LAPLACEXZ_H__ +#endif // BOUT_LAPLACEXZ_H diff --git a/include/bout/invert_laplace.hxx b/include/bout/invert_laplace.hxx index c4ae5efdf8..0b416d4aab 100644 --- a/include/bout/invert_laplace.hxx +++ b/include/bout/invert_laplace.hxx @@ -31,8 +31,8 @@ class Laplacian; -#ifndef __LAPLACE_H__ -#define __LAPLACE_H__ +#ifndef BOUT_LAPLACE_H +#define BOUT_LAPLACE_H #include "bout/build_config.hxx" @@ -238,6 +238,10 @@ public: virtual void setInnerBoundaryFlags(int f) { inner_boundary_flags = f; } virtual void setOuterBoundaryFlags(int f) { outer_boundary_flags = f; } + virtual int getGlobalFlags() const { return global_flags; } + virtual int getInnerBoundaryFlags() const { return inner_boundary_flags; } + virtual int getOuterBoundaryFlags() const { return outer_boundary_flags; } + /// Does this solver use Field3D coefficients (true) or only their DC component (false) virtual bool uses3DCoefs() const { return false; } @@ -275,8 +279,8 @@ public: /// performance information, with optional name for the time /// dimension void outputVars(Options& output_options) const { outputVars(output_options, "t"); } - virtual void outputVars(MAYBE_UNUSED(Options& output_options), - MAYBE_UNUSED(const std::string& time_dimension)) const {} + virtual void outputVars([[maybe_unused]] Options& output_options, + [[maybe_unused]] const std::string& time_dimension) const {} /// Register performance monitor with \p solver, prefix output with /// `Options` section name @@ -308,9 +312,23 @@ protected: int extra_yguards_lower; ///< exclude some number of points at the lower boundary, useful for staggered grids or when boundary conditions make inversion redundant int extra_yguards_upper; ///< exclude some number of points at the upper boundary, useful for staggered grids or when boundary conditions make inversion redundant - int global_flags; ///< Default flags - int inner_boundary_flags; ///< Flags to set inner boundary condition - int outer_boundary_flags; ///< Flags to set outer boundary condition + /// Return true if global/default \p flag is set + bool isGlobalFlagSet(int flag) const { return (global_flags & flag) != 0; } + /// Return true if \p flag is set for the inner boundary condition + bool isInnerBoundaryFlagSet(int flag) const { + return (inner_boundary_flags & flag) != 0; + } + /// Return true if \p flag is set for the outer boundary condition + bool isOuterBoundaryFlagSet(int flag) const { + return (outer_boundary_flags & flag) != 0; + } + + /// Return true if \p flag is set for the inner boundary condition + /// and this is the first proc in X direction + bool isInnerBoundaryFlagSetOnFirstX(int flag) const; + /// Return true if \p flag is set for the outer boundary condition + /// and this the last proc in X direction + bool isOuterBoundaryFlagSetOnLastX(int flag) const; void tridagCoefs(int jx, int jy, BoutReal kwave, dcomplex& a, dcomplex& b, dcomplex& c, const Field2D* ccoef = nullptr, const Field2D* d = nullptr, @@ -322,15 +340,13 @@ protected: CELL_LOC loc = CELL_DEFAULT); void tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dcomplex* bk, int jy, - int kz, BoutReal kwave, int flags, int inner_boundary_flags, - int outer_boundary_flags, const Field2D* a, const Field2D* ccoef, + int kz, BoutReal kwave, const Field2D* a, const Field2D* ccoef, const Field2D* d, bool includeguards = true, bool zperiodic = true) { - tridagMatrix(avec, bvec, cvec, bk, jy, kz, kwave, flags, inner_boundary_flags, - outer_boundary_flags, a, ccoef, ccoef, d, includeguards, zperiodic); + tridagMatrix(avec, bvec, cvec, bk, jy, kz, kwave, a, ccoef, ccoef, d, includeguards, + zperiodic); } void tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dcomplex* bk, int jy, - int kz, BoutReal kwave, int flags, int inner_boundary_flags, - int outer_boundary_flags, const Field2D* a, const Field2D* c1coef, + int kz, BoutReal kwave, const Field2D* a, const Field2D* c1coef, const Field2D* c2coef, const Field2D* d, bool includeguards = true, bool zperiodic = true); CELL_LOC location; ///< staggered grid location of this solver @@ -339,6 +355,10 @@ protected: /// localmesh->getCoordinates(location) once private: + int global_flags; ///< Default flags + int inner_boundary_flags; ///< Flags to set inner boundary condition + int outer_boundary_flags; ///< Flags to set outer boundary condition + /// Singleton instance static std::unique_ptr instance; /// Name for writing performance infomation; default taken from @@ -374,4 +394,4 @@ void laplace_tridag_coefs(int jx, int jy, int jz, dcomplex& a, dcomplex& b, dcom const Field2D* ccoef = nullptr, const Field2D* d = nullptr, CELL_LOC loc = CELL_DEFAULT); -#endif // __LAPLACE_H__ +#endif // BOUT_LAPLACE_H diff --git a/include/bout/invert_parderiv.hxx b/include/bout/invert_parderiv.hxx index 5a83a7f4e8..e9623e0f9f 100644 --- a/include/bout/invert_parderiv.hxx +++ b/include/bout/invert_parderiv.hxx @@ -28,8 +28,8 @@ * ************************************************************************/ -#ifndef __INV_PAR_H__ -#define __INV_PAR_H__ +#ifndef BOUT_INV_PAR_H +#define BOUT_INV_PAR_H #include "bout/field2d.hxx" #include "bout/field3d.hxx" @@ -189,4 +189,4 @@ protected: private: }; -#endif // __INV_PAR_H__ +#endif // BOUT_INV_PAR_H diff --git a/include/bout/invert_pardiv.hxx b/include/bout/invert_pardiv.hxx index 23ea59e943..0153cc1987 100644 --- a/include/bout/invert_pardiv.hxx +++ b/include/bout/invert_pardiv.hxx @@ -31,11 +31,11 @@ #ifndef INV_PARDIV_H #define INV_PARDIV_H -#include "field2d.hxx" -#include "field3d.hxx" -#include "options.hxx" -#include "unused.hxx" +#include "bout/field2d.hxx" +#include "bout/field3d.hxx" #include "bout/generic_factory.hxx" +#include "bout/options.hxx" +#include "bout/unused.hxx" // Pardivergence implementations constexpr auto PARDIVCYCLIC = "cyclic"; diff --git a/include/bout/invertable_operator.hxx b/include/bout/invertable_operator.hxx index 7168324b75..a45fc3565f 100644 --- a/include/bout/invertable_operator.hxx +++ b/include/bout/invertable_operator.hxx @@ -30,8 +30,8 @@ class InvertableOperator; }; }; // namespace bout -#ifndef __INVERTABLE_OPERATOR_H__ -#define __INVERTABLE_OPERATOR_H__ +#ifndef BOUT_INVERTABLE_OPERATOR_H +#define BOUT_INVERTABLE_OPERATOR_H #include "bout/build_config.hxx" @@ -120,7 +120,7 @@ PetscErrorCode petscVecToField(Vec in, T& out) { template class InvertableOperator { static_assert( - bout::utils::is_Field::value, + bout::utils::is_Field_v, "InvertableOperator must be templated with one of FieldPerp, Field2D or Field3D"); public: @@ -197,7 +197,7 @@ public: } // Add the RGN_WITHBNDRIES region to the mesh. Requires RGN_NOBNDRY to be defined. - if (std::is_same::value) { + if constexpr (std::is_same_v) { if (not localmesh->hasRegion3D("RGN_WITHBNDRIES")) { // This avoids all guard cells and corners but includes boundaries // Note we probably don't want to include periodic boundaries as these @@ -242,7 +242,7 @@ public: localmesh->addRegion3D("RGN_WITHBNDRIES", nocorner3D); } - } else if (std::is_same::value) { + } else if constexpr (std::is_same_v) { if (not localmesh->hasRegion2D("RGN_WITHBNDRIES")) { // This avoids all guard cells and corners but includes boundaries Region nocorner2D = localmesh->getRegion2D("RGN_NOBNDRY"); @@ -280,7 +280,7 @@ public: localmesh->addRegion2D("RGN_WITHBNDRIES", nocorner2D); } - } else if (std::is_same::value) { + } else if constexpr (std::is_same_v) { if (not localmesh->hasRegionPerp("RGN_WITHBNDRIES")) { // This avoids all guard cells and corners but includes boundaries Region nocornerPerp = localmesh->getRegionPerp("RGN_NOBNDRY"); diff --git a/include/bout/lapack_routines.hxx b/include/bout/lapack_routines.hxx index 70a3128f81..d81c0b422d 100644 --- a/include/bout/lapack_routines.hxx +++ b/include/bout/lapack_routines.hxx @@ -20,8 +20,8 @@ * **************************************************************************/ -#ifndef __LAPACK_ROUTINES_H__ -#define __LAPACK_ROUTINES_H__ +#ifndef BOUT_LAPACK_ROUTINES_H +#define BOUT_LAPACK_ROUTINES_H #include @@ -56,4 +56,4 @@ void cyclic_tridag(dcomplex* a, dcomplex* b, dcomplex* c, dcomplex* r, dcomplex* /// Complex band matrix solver void cband_solve(Matrix& a, int n, int m1, int m2, Array& b); -#endif // __LAPACK_ROUTINES_H__ +#endif // BOUT_LAPACK_ROUTINES_H diff --git a/include/bout/macro_for_each.hxx b/include/bout/macro_for_each.hxx index 10cbd21818..1cfe373c3f 100644 --- a/include/bout/macro_for_each.hxx +++ b/include/bout/macro_for_each.hxx @@ -1,6 +1,6 @@ -#ifndef __MACRO_FOR_EACH_H__ -#define __MACRO_FOR_EACH_H__ +#ifndef BOUT_MACRO_FOR_EACH_H +#define BOUT_MACRO_FOR_EACH_H // Provides a macro MACRO_FOR_EACH which applies a // macro to each argument in a VA_ARGS list diff --git a/include/bout/mask.hxx b/include/bout/mask.hxx index 19c8ea86fd..4250d21105 100644 --- a/include/bout/mask.hxx +++ b/include/bout/mask.hxx @@ -19,8 +19,8 @@ * along with BOUT++. If not, see . **************************************************************************/ -#ifndef __MASK_H__ -#define __MASK_H__ +#ifndef BOUT_MASK_H +#define BOUT_MASK_H #include @@ -66,6 +66,17 @@ public: inline bool& operator()(int jx, int jy, int jz) { return mask(jx, jy, jz); } inline const bool& operator()(int jx, int jy, int jz) const { return mask(jx, jy, jz); } + inline const bool& operator[](const Ind3D& i) const { return mask[i]; } }; -#endif //__MASK_H__ +inline std::unique_ptr> regionFromMask(const BoutMask& mask, + const Mesh* mesh) { + std::vector indices; + for (auto i : mesh->getRegion("RGN_ALL")) { + if (not mask(i.x(), i.y(), i.z())) { + indices.push_back(i); + } + } + return std::make_unique>(indices); +} +#endif //BOUT_MASK_H diff --git a/include/bout/mesh.hxx b/include/bout/mesh.hxx index 45ea392482..c80716fc12 100644 --- a/include/bout/mesh.hxx +++ b/include/bout/mesh.hxx @@ -40,8 +40,8 @@ class Mesh; -#ifndef __MESH_H__ -#define __MESH_H__ +#ifndef BOUT_MESH_H +#define BOUT_MESH_H #include "mpi.h" @@ -55,25 +55,28 @@ class Mesh; #include "bout/field_data.hxx" #include "bout/options.hxx" -#include "fieldgroup.hxx" +#include "bout/fieldgroup.hxx" -#include "bout/boundary_region.hxx" -#include "bout/parallel_boundary_region.hxx" +class BoundaryRegion; +class BoundaryRegionPar; -#include "sys/range.hxx" // RangeIterator +#include "bout/sys/range.hxx" // RangeIterator #include -#include "coordinates.hxx" // Coordinates class +#include "bout/coordinates.hxx" // Coordinates class #include "bout/unused.hxx" #include "bout/generic_factory.hxx" #include +#include + #include #include #include +#include #include #include @@ -89,6 +92,9 @@ public: ReturnType create(Options* options = nullptr, GridDataSource* source = nullptr) const; }; +BOUT_ENUM_CLASS(BoundaryParType, all, xin, xout, fwd, bwd, xin_fwd, xout_fwd, xin_bwd, + xout_bwd, SIZE); + template using RegisterMesh = MeshFactory::RegisterInFactory; @@ -134,7 +140,7 @@ public: /// Add output variables to \p output_options /// These are used for post-processing - virtual void outputVars(MAYBE_UNUSED(Options& output_options)) {} + virtual void outputVars([[maybe_unused]] Options& output_options) {} // Get routines to request data from mesh file @@ -484,11 +490,20 @@ public: /// Add a boundary region to this processor virtual void addBoundary(BoundaryRegion* UNUSED(bndry)) {} - /// Get all the parallel (Y) boundaries on this processor - virtual std::vector getBoundariesPar() = 0; + /// Get the list of parallel boundary regions. The option specifies with + /// region to get. Default is to get all regions. All possible options are + /// listed at the top of this file, see BoundaryParType. + /// For example: + /// get all regions: + /// mesh->getBoundariesPar(Mesh::BoundaryParType::all) + /// get only xout: + /// mesh->getBoundariesPar(Mesh::BoundaryParType::xout) + virtual std::vector> + getBoundariesPar(BoundaryParType type = BoundaryParType::all) = 0; /// Add a parallel(Y) boundary to this processor - virtual void addBoundaryPar(BoundaryRegionPar* UNUSED(bndry)) {} + virtual void addBoundaryPar(std::shared_ptr UNUSED(bndry), + BoundaryParType UNUSED(type)) {} /// Branch-cut special handling (experimental) virtual Field3D smoothSeparatrix(const Field3D& f) { return f; } @@ -503,9 +518,20 @@ public: int GlobalNx, GlobalNy, GlobalNz; ///< Size of the global arrays. Note: can have holes /// Size of the global arrays excluding boundary points. int GlobalNxNoBoundaries, GlobalNyNoBoundaries, GlobalNzNoBoundaries; + + /// Note: These offsets only correct if Y guards are not included in the global array + /// and are corrected in gridfromfile.cxx int OffsetX, OffsetY, OffsetZ; ///< Offset of this mesh within the global array ///< so startx on this processor is OffsetX in global + /// Map between local and global indices + /// (MapGlobalX, MapGlobalY, MapGlobalZ) in the global index space maps to (MapLocalX, MapLocalY, MapLocalZ) locally. + /// Note that boundary cells are included in the global index space, but communication + /// guard cells are not. + int MapGlobalX, MapGlobalY, MapGlobalZ; ///< Start global indices + int MapLocalX, MapLocalY, MapLocalZ; ///< Start local indices + int MapCountX, MapCountY, MapCountZ; ///< Size of the mapped region + /// Returns the number of unique cells (i.e., ones not used for /// communication) on this processor for 3D fields. Boundaries /// are only included to a depth of 1. @@ -795,6 +821,14 @@ public: // Switch for communication of corner guard and boundary cells const bool include_corner_cells; + std::optional getCommonRegion(std::optional, std::optional); + size_t getRegionID(const std::string& region) const; + const Region& getRegion(size_t RegionID) const { return region3D[RegionID]; } + const Region& getRegion(std::optional RegionID) const { + ASSERT1(RegionID.has_value()); + return region3D[RegionID.value()]; + } + private: /// Allocates default Coordinates objects /// By default attempts to read staggered Coordinates from grid data source, @@ -807,7 +841,9 @@ private: bool force_interpolate_from_centre = false); //Internal region related information - std::map> regionMap3D; + std::map regionMap3D; + std::vector> region3D; + std::vector> region3Dintersect; std::map> regionMap2D; std::map> regionMapPerp; Array indexLookup3Dto2D; @@ -831,4 +867,4 @@ Mesh::getRegion(const std::string& region_name) const { return getRegionPerp(region_name); } -#endif // __MESH_H__ +#endif // BOUT_MESH_H diff --git a/include/bout/monitor.hxx b/include/bout/monitor.hxx index eb86c01554..359096e74f 100644 --- a/include/bout/monitor.hxx +++ b/include/bout/monitor.hxx @@ -1,5 +1,5 @@ -#ifndef __MONITOR_H__ -#define __MONITOR_H__ +#ifndef BOUT_MONITOR_H +#define BOUT_MONITOR_H #include "bout/assert.hxx" #include "bout/bout_types.hxx" @@ -50,8 +50,8 @@ public: /// Callback function for when a clean shutdown is initiated virtual void cleanup(){}; - virtual void outputVars(MAYBE_UNUSED(Options& options), - MAYBE_UNUSED(const std::string& time_dimension)) {} + virtual void outputVars([[maybe_unused]] Options& options, + [[maybe_unused]] const std::string& time_dimension) {} protected: /// Get the currently set timestep for this monitor @@ -125,4 +125,4 @@ public: void writeProgress(BoutReal simtime, bool output_split); }; -#endif // __MONITOR_H__ +#endif // BOUT_MONITOR_H diff --git a/include/bout/mpi_wrapper.hxx b/include/bout/mpi_wrapper.hxx index 65b14cf84f..826405d8da 100644 --- a/include/bout/mpi_wrapper.hxx +++ b/include/bout/mpi_wrapper.hxx @@ -27,8 +27,8 @@ class MpiWrapper; -#ifndef __MPIWRAPPER_H__ -#define __MPIWRAPPER_H__ +#ifndef BOUT_MPIWRAPPER_H +#define BOUT_MPIWRAPPER_H #include @@ -153,4 +153,4 @@ public: virtual double MPI_Wtime() { return ::MPI_Wtime(); } }; -#endif // __MPIWRAPPER_H__ +#endif // BOUT_MPIWRAPPER_H diff --git a/include/bout/msg_stack.hxx b/include/bout/msg_stack.hxx index cc19a7b9f6..adbf1bbbcb 100644 --- a/include/bout/msg_stack.hxx +++ b/include/bout/msg_stack.hxx @@ -26,12 +26,11 @@ class MsgStack; -#ifndef __MSG_STACK_H__ -#define __MSG_STACK_H__ +#ifndef BOUT_MSG_STACK_H +#define BOUT_MSG_STACK_H #include "bout/build_config.hxx" -#include "bout/format.hxx" #include "bout/unused.hxx" #include "fmt/core.h" @@ -131,20 +130,8 @@ GLOBAL MsgStack msg_stack; * constructor, and pops the message on destruction. */ class MsgStackItem { - /// Backfill for C++14: note this _wrong_ and only useful for our - /// purposes here, that is, telling us if there has been an uncaught - /// exception, which is why this is a private method - static int uncaught_exceptions() { -#if __cpp_lib_uncaught_exceptions >= 201411L - // C++17 version - return std::uncaught_exceptions(); -#else - // C++14 version - return static_cast(std::uncaught_exception()); -#endif - } // Number of uncaught exceptions when this instance was created - int exception_count = uncaught_exceptions(); + int exception_count = std::uncaught_exceptions(); public: // Not currently used anywhere @@ -162,7 +149,7 @@ public: line, file)) {} ~MsgStackItem() { // If an exception has occurred, don't pop the message - if (exception_count == uncaught_exceptions()) { + if (exception_count == std::uncaught_exceptions()) { msg_stack.pop(point); } } @@ -201,7 +188,7 @@ private: arguments and the optional arguments follow from there. */ #define TRACE(...) \ - MsgStackItem CONCATENATE(msgTrace_, __LINE__)(__FILE__, __LINE__, __VA_ARGS__) + const MsgStackItem CONCATENATE(msgTrace_, __LINE__)(__FILE__, __LINE__, __VA_ARGS__) #else #define TRACE(...) #endif @@ -225,4 +212,4 @@ private: */ #define AUTO_TRACE() TRACE(__thefunc__) // NOLINT -#endif // __MSG_STACK_H__ +#endif // BOUT_MSG_STACK_H diff --git a/include/bout/multiostream.hxx b/include/bout/multiostream.hxx index b90ccf9419..ca3cc2d0c7 100644 --- a/include/bout/multiostream.hxx +++ b/include/bout/multiostream.hxx @@ -1,5 +1,5 @@ -#ifndef __MULTIOSTREAM_H__ -#define __MULTIOSTREAM_H__ +#ifndef BOUT_MULTIOSTREAM_H +#define BOUT_MULTIOSTREAM_H #include #include @@ -89,4 +89,4 @@ public: using cmultiostream = multiostream; using wmultiostream = multiostream; -#endif // __MULTIOSTREAM_H__ +#endif // BOUT_MULTIOSTREAM_H diff --git a/include/bout/openmpwrap.hxx b/include/bout/openmpwrap.hxx index 032705e61a..582df7b86c 100644 --- a/include/bout/openmpwrap.hxx +++ b/include/bout/openmpwrap.hxx @@ -24,9 +24,16 @@ * **************************************************************************/ -#ifndef __OPENMPWRAP_H__ -#define __OPENMPWRAP_H__ +#ifndef BOUT_OPENMPWRAP_H +#define BOUT_OPENMPWRAP_H +#include "bout/build_defines.hxx" + +#if BOUT_USE_OPENMP || defined(_OPENMP) +#include "omp.h" +#endif + +#ifdef _OPENMP //Some helpers for indirection -- required so that the _Pragma gets "omp " //where is any number of valid omp options/environments (e.g. atomic, critical etc.) #define INDIRECT0(a) #a @@ -35,12 +42,30 @@ //Define a macro wrapper to the use of `#pragma omp` to avoid unknown pragma //warnings when compiling without openmp support. -#if BOUT_USE_OPENMP +#define BOUT_OMP_SAFE(...) _Pragma(INDIRECT2(__VA_ARGS__)) #define BOUT_OMP(...) _Pragma(INDIRECT2(__VA_ARGS__)) #else +#define BOUT_OMP_SAFE(...) #define BOUT_OMP(...) #endif +#if BOUT_USE_OPENMP + +#ifndef INDIRECT2 +#error expected macro INDIRECT2 to be available +#endif + +#define BOUT_OMP_PERF(...) _Pragma(INDIRECT2(__VA_ARGS__)) +#else +#define BOUT_OMP_PERF(...) +#endif + +#ifndef _OPENMP +inline int constexpr omp_get_max_threads() { return 1; } +inline int constexpr omp_get_num_threads() { return 1; } +inline int constexpr omp_get_thread_num() { return 0; } +#endif + //Perhaps want to cleanup local helpers with below, but DON'T! //This would cause uses of BOUT_OMP to break // #undef INDIRECT0 diff --git a/include/bout/operatorstencil.hxx b/include/bout/operatorstencil.hxx index c6a26c246f..118dc7a068 100644 --- a/include/bout/operatorstencil.hxx +++ b/include/bout/operatorstencil.hxx @@ -27,8 +27,8 @@ * **************************************************************************/ -#ifndef __OPERATORSTENCIL_H__ -#define __OPERATORSTENCIL_H__ +#ifndef BOUT_OPERATORSTENCIL_H +#define BOUT_OPERATORSTENCIL_H #include #include @@ -45,9 +45,9 @@ /// subtracted from them. template struct IndexOffset { - static_assert(std::is_same::value || std::is_same::value - || std::is_same::value, - "IndexOffset only works with SpecificInd types"); + static_assert( + std::is_same_v || std::is_same_v || std::is_same_v, + "IndexOffset only works with SpecificInd types"); int dx = 0, dy = 0, dz = 0; const inline IndexOffset xp(int delta_x = 1) const { return {dx + delta_x, dy, dz}; } @@ -133,9 +133,9 @@ using OffsetIndPerp = IndexOffset; template class OperatorStencil { public: - static_assert(std::is_same::value || std::is_same::value - || std::is_same::value, - "OperatorStencil only works with SpecificInd types"); + static_assert( + std::is_same_v || std::is_same_v || std::is_same_v, + "OperatorStencil only works with SpecificInd types"); using offset = IndexOffset; using stencil_part = std::vector; using stencil_test = std::function; @@ -246,7 +246,7 @@ OperatorStencil squareStencil(Mesh* localmesh) { zero.xp(), zero.xm(), }; - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { offsets.insert(zero.yp()); offsets.insert(zero.ym()); offsets.insert(zero.xp().yp()); @@ -254,7 +254,7 @@ OperatorStencil squareStencil(Mesh* localmesh) { offsets.insert(zero.xm().yp()); offsets.insert(zero.xm().ym()); } - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { offsets.insert(zero.zp()); offsets.insert(zero.zm()); offsets.insert(zero.xp().zp()); @@ -262,7 +262,7 @@ OperatorStencil squareStencil(Mesh* localmesh) { offsets.insert(zero.xm().zp()); offsets.insert(zero.xm().zm()); } - if (std::is_same::value) { + if constexpr (std::is_same_v) { offsets.insert(zero.yp().zp()); offsets.insert(zero.yp().zm()); offsets.insert(zero.ym().zp()); @@ -271,11 +271,14 @@ OperatorStencil squareStencil(Mesh* localmesh) { std::vector> offsetsVec(offsets.begin(), offsets.end()); stencil.add( [localmesh](T ind) -> bool { - return (localmesh->xstart <= ind.x() && ind.x() <= localmesh->xend - && (std::is_same::value - || (localmesh->ystart <= ind.y() && ind.y() <= localmesh->yend)) - && (std::is_same::value - || (localmesh->zstart <= ind.z() && ind.z() <= localmesh->zend))); + return ( + localmesh->xstart <= ind.x() && ind.x() <= localmesh->xend + && (std::is_same_v< + T, + IndPerp> || (localmesh->ystart <= ind.y() && ind.y() <= localmesh->yend)) + && (std::is_same_v< + T, + Ind2D> || (localmesh->zstart <= ind.z() && ind.z() <= localmesh->zend))); }, offsetsVec); stencil.add([](T UNUSED(ind)) -> bool { return true; }, {zero}); @@ -294,26 +297,29 @@ OperatorStencil starStencil(Mesh* localmesh) { zero.xp(), zero.xm(), }; - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { offsets.insert(zero.yp()); offsets.insert(zero.ym()); } - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { offsets.insert(zero.zp()); offsets.insert(zero.zm()); } std::vector> offsetsVec(offsets.begin(), offsets.end()); stencil.add( [localmesh](T ind) -> bool { - return (localmesh->xstart <= ind.x() && ind.x() <= localmesh->xend - && (std::is_same::value - || (localmesh->ystart <= ind.y() && ind.y() <= localmesh->yend)) - && (std::is_same::value - || (localmesh->zstart <= ind.z() && ind.z() <= localmesh->zend))); + return ( + localmesh->xstart <= ind.x() && ind.x() <= localmesh->xend + && (std::is_same_v< + T, + IndPerp> || (localmesh->ystart <= ind.y() && ind.y() <= localmesh->yend)) + && (std::is_same_v< + T, + Ind2D> || (localmesh->zstart <= ind.z() && ind.z() <= localmesh->zend))); }, offsetsVec); stencil.add([](T UNUSED(ind)) -> bool { return true; }, {zero}); return stencil; } -#endif // __OPERATORSTENCIL_H__ +#endif // BOUT_OPERATORSTENCIL_H diff --git a/include/bout/options.hxx b/include/bout/options.hxx index bf1704100f..4a32907b17 100644 --- a/include/bout/options.hxx +++ b/include/bout/options.hxx @@ -12,9 +12,9 @@ * options and allows access to all sub-sections * ************************************************************************** -* Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu +* Copyright 2010-2024 BOUT++ contributors * -* Contact: Ben Dudson, bd512@york.ac.uk +* Contact: Ben Dudson, dudson2@llnl.gov * * This file is part of BOUT++. * @@ -36,8 +36,8 @@ class Options; #pragma once -#ifndef __OPTIONS_H__ -#define __OPTIONS_H__ +#ifndef OPTIONS_H +#define OPTIONS_H #include "bout/bout_types.hxx" #include "bout/field2d.hxx" @@ -53,7 +53,6 @@ class Options; #include #include -#include #include #include #include @@ -156,6 +155,30 @@ class Options; * This is used to represent all the options passed to BOUT++ either in a file or on the * command line. * + * Copying options + * --------------- + * + * The copy constructor and copy assignment operator are deleted, so + * this is a compile-time error: + * + * Options options2 = options1["value"]; + * + * This is because it's ambiguous what is meant, and because accidental copies + * were a frequent source of hard-to-understand bugs. Usually a reference is + * intended, rather than a copy: + * + * Options& ref = options1["value"]; + * + * so that changes to `ref` or its children are reflected in `options1`. + * If the intent is to copy the value of the option, then just copy that: + * + * option2.value = options1["value"].value; + * + * If a full deep copy of the option, its attributes and children + * (recursively) is really desired, then use the `copy()` method: + * + * Options options2 = options1["value"].copy(); + * */ class Options { public: @@ -176,14 +199,68 @@ public: assign(value); } + /// The type used to store values + using ValueType = + bout::utils::variant, Matrix, Tensor>; + + /// A tree representation with leaves containing ValueType. + /// Used to construct Options from initializer lists. + /// + /// Note: Either there are children OR value is assigned + struct CopyableOptions { + template + CopyableOptions(T value) : value(std::move(value)) {} + + /// Special case for char*, which can otherwise become cast to bool + CopyableOptions(const char* value) : value(std::string(value)) {} + + CopyableOptions( + std::initializer_list> children) + : children(children) {} + ValueType value; + std::initializer_list> children; + }; + + /// Type of initializer_list that can be used to create Options + /// This is a workaround for initializer_lists not being movable. + using InitializerList = std::initializer_list>; + /// Construct with a nested initializer list - /// This allows Options trees to be constructed, using a mix of types. + /// This allows Options trees to be constructed using a mix of types. /// /// Example: { {"key1", 42}, {"key2", field} } - Options(std::initializer_list> values); + /// + /// Note: Options doesn't have a copy constructor, and initializer lists + /// don't play nicely with uncopyable types. Instead, we create + /// a tree of CopyableOptions and then move. + Options(InitializerList values, Options* parent_instance = nullptr, + std::string section_name = ""); - /// Copy constructor - Options(const Options& other); + /// Options must be explicitly copied + /// + /// Option option2 = option1.copy(); + /// + [[deprecated("Please use a reference or .copy() instead")]] Options( + const Options& other); + + /// Copy assignment must be explicit + /// + /// Option option2 = option1.copy(); + /// + /// Note that the value can be copied using: + /// + /// option2.value = option1.value; + /// + [[deprecated("Please use a reference or .copy() instead")]] Options& + operator=(const Options& other); // Use a reference or .copy() method + + /// Make a deep copy of this Options, + /// recursively copying children. + Options copy() const; + + Options(Options&& other) noexcept; + Options& operator=(Options&& other) noexcept; ~Options() = default; @@ -193,11 +270,6 @@ public: /// Free all memory static void cleanup(); - /// The type used to store values - using ValueType = - bout::utils::variant, Matrix, Tensor>; - /// The type used to store attributes /// Extends the variant class so that cast operator can be implemented /// and assignment operator overloaded @@ -210,14 +282,11 @@ public: public: using Base = bout::utils::variant; - /// Constructor AttributeType() = default; - /// Copy constructor AttributeType(const AttributeType& other) = default; - /// Move constructor - AttributeType(AttributeType&& other) : Base(std::move(other)) {} - - /// Destructor + AttributeType(AttributeType&& other) = default; + AttributeType& operator=(const AttributeType& other) = default; + AttributeType& operator=(AttributeType&& other) = default; ~AttributeType() = default; /// Assignment operator, including move assignment @@ -229,9 +298,6 @@ public: return *this; } - /// Copy assignment operator - AttributeType& operator=(const AttributeType& other) = default; - /// Initialise with a value /// This enables AttributeTypes to be constructed using initializer lists template @@ -300,7 +366,8 @@ public: /// {"long_name", "some velocity"} /// }); Options& setAttributes( - std::initializer_list> attrs) { + const std::initializer_list>& + attrs) { for (const auto& attr : attrs) { attributes[attr.first] = attr.second; } @@ -362,15 +429,6 @@ public: return inputvalue; } - /// Copy assignment - /// - /// This replaces the value, attributes and all children - /// - /// Note that if only the value is desired, then that can be copied using - /// the value member directly e.g. option2.value = option1.value; - /// - Options& operator=(const Options& other); - /// Assign a value to the option. /// This will throw an exception if already has a value /// @@ -382,9 +440,9 @@ public: /// Note: Specialised versions for types stored in ValueType template void assign(T val, std::string source = "") { - std::stringstream ss; - ss << val; - _set(ss.str(), std::move(source), false); + std::stringstream as_str; + as_str << val; + _set(as_str.str(), std::move(source), false); } /// Force to a value @@ -462,20 +520,20 @@ public: // If the variant is a string then we may be able to parse it if (bout::utils::holds_alternative(value)) { - std::stringstream ss(bout::utils::get(value)); - ss >> val; + std::stringstream as_str(bout::utils::get(value)); + as_str >> val; // Check if the parse failed - if (ss.fail()) { + if (as_str.fail()) { throw BoutException("Option {:s} could not be parsed ('{:s}')", full_name, bout::utils::variantToString(value)); } // Check if there are characters remaining std::string remainder; - std::getline(ss, remainder); - for (const char& ch : remainder) { - if (!std::isspace(static_cast(ch))) { + std::getline(as_str, remainder); + for (const unsigned char chr : remainder) { + if (!std::isspace(chr)) { // Meaningful character not parsed throw BoutException("Option {:s} could not be parsed", full_name); } @@ -495,7 +553,7 @@ public: // Specify the source of the setting output_info << " (" << bout::utils::variantToString(attributes.at("source")) << ")"; } - output_info << endl; + output_info << '\n'; return val; } @@ -514,7 +572,7 @@ public: value_used = true; // Mark the option as used output_info << _("\tOption ") << full_name << " = " << def << " (" << DEFAULT_SOURCE - << ")" << std::endl; + << ")\n"; return def; } T val = as(def); @@ -543,11 +601,11 @@ public: ASSERT0(def.isValue()); if (is_section) { - // Option not found - *this = def; + // Option not found. Copy the value from the default. + this->_set_no_check(def.value, DEFAULT_SOURCE); output_info << _("\tOption ") << full_name << " = " << def.full_name << " (" - << DEFAULT_SOURCE << ")" << std::endl; + << DEFAULT_SOURCE << ")\n"; } else { // Check if this was previously set as a default option if (bout::utils::variantEqualTo(attributes.at("source"), DEFAULT_SOURCE)) { @@ -571,7 +629,7 @@ public: if (is_section) { // Option not found output_info << _("\tOption ") << full_name << " = " << def << " (" << DEFAULT_SOURCE - << ")" << std::endl; + << ")\n"; return def; } T val = as(def); @@ -657,8 +715,8 @@ public: // Setting options template - void forceSet(const std::string& key, T t, const std::string& source = "") { - (*this)[key].force(t, source); + void forceSet(const std::string& key, T val, const std::string& source = "") { + (*this)[key].force(val, source); } /*! @@ -670,11 +728,11 @@ public: if (!is_section) { return false; } - auto it = children.find(key); - if (it == children.end()) { + auto child = children.find(key); + if (child == children.end()) { return false; } - return it->second.isSet(); + return child->second.isSet(); } /// Get options, passing in a reference to a variable @@ -702,13 +760,12 @@ public: /// Print just the name of this object without parent sections std::string name() const { - auto pos = full_name.rfind(":"); + auto pos = full_name.rfind(':'); if (pos == std::string::npos) { // No parent section or sections return full_name; - } else { - return full_name.substr(pos + 1); } + return full_name.substr(pos + 1); } /// Return a new Options instance which contains all the values @@ -731,21 +788,6 @@ public: /// clean the cache of parsed options static void cleanCache(); - /*! - * Class used to store values, together with - * information about their origin and usage - */ - struct OptionValue { - std::string value; - std::string source; // Source of the setting - mutable bool used = false; // Set to true when used - - /// This constructor needed for map::emplace - /// Can be removed in C++17 with map::insert and brace initialisation - OptionValue(std::string value, std::string source, bool used) - : value(std::move(value)), source(std::move(source)), used(used) {} - }; - /// Read-only access to internal options and sections /// to allow iteration over the tree std::map subsections() const; @@ -784,8 +826,6 @@ private: /// The source label given to default values static const std::string DEFAULT_SOURCE; - static Options* root_instance; ///< Only instance of the root section - Options* parent_instance{nullptr}; std::string full_name; // full path name for logging only @@ -837,8 +877,8 @@ private: /// Tests if two values are similar. template - bool similar(T a, T b) const { - return a == b; + bool similar(T lhs, T rhs) const { + return lhs == rhs; } }; @@ -862,7 +902,7 @@ inline void Options::assign<>(std::string val, std::string source) { // Note: const char* version needed to avoid conversion to bool template <> inline void Options::assign<>(const char* val, std::string source) { - _set(std::string(val), source, false); + _set(std::string(val), std::move(source), false); } // Note: Field assignments don't check for previous assignment (always force) template <> @@ -880,8 +920,8 @@ void Options::assign<>(Tensor val, std::string source); /// Specialised similar comparison methods template <> -inline bool Options::similar(BoutReal a, BoutReal b) const { - return fabs(a - b) < 1e-10; +inline bool Options::similar(BoutReal lhs, BoutReal rhs) const { + return fabs(lhs - rhs) < 1e-10; } /// Specialised as routines @@ -941,7 +981,7 @@ namespace details { /// avoiding lengthy recompilation if we change it struct OptionsFormatterBase { auto parse(fmt::format_parse_context& ctx) -> fmt::format_parse_context::iterator; - auto format(const Options& options, fmt::format_context& ctx) + auto format(const Options& options, fmt::format_context& ctx) const -> fmt::format_context::iterator; private: @@ -972,6 +1012,8 @@ private: template <> struct fmt::formatter : public bout::details::OptionsFormatterBase {}; +// NOLINTBEGIN(cppcoreguidelines-macro-usage) + /// Define for reading options which passes the variable name #define OPTION(options, var, def) pointer(options)->get(#var, var, def) @@ -1032,4 +1074,6 @@ struct fmt::formatter : public bout::details::OptionsFormatterBase {}; __LINE__) = Options::root()[name].overrideDefault(value); \ } -#endif // __OPTIONS_H__ +// NOLINTEND(cppcoreguidelines-macro-usage) + +#endif // OPTIONS_H diff --git a/include/bout/options_io.hxx b/include/bout/options_io.hxx new file mode 100644 index 0000000000..57be8bbaae --- /dev/null +++ b/include/bout/options_io.hxx @@ -0,0 +1,177 @@ +/// Parent class for IO to binary files and streams +/// +/// +/// Usage: +/// +/// 1. Dump files, containing time history: +/// +/// auto dump = OptionsIOFactory::getInstance().createOutput(); +/// dump->write(data); +/// +/// where data is an Options tree. By default dump files are configured +/// with the root `output` section, or an Option tree can be passed to +/// `createOutput`. +/// +/// 2. Restart files: +/// +/// auto restart = OptionsIOFactory::getInstance().createOutput(); +/// restart->write(data); +/// +/// where data is an Options tree. By default restart files are configured +/// with the root `restart_files` section, or an Option tree can be passed to +/// `createRestart`. +/// +/// 3. Ad-hoc single files +/// Note: The caller should consider how multiple processors interact with the file. +/// +/// auto file = OptionsIOFactory::getInstance().createFile("some_file.nc"); +/// or +/// auto file = OptionsIO::create("some_file.nc"); +/// +/// + +#pragma once + +#ifndef OPTIONS_IO_H +#define OPTIONS_IO_H + +#include "bout/build_config.hxx" +#include "bout/generic_factory.hxx" +#include "bout/options.hxx" + +#include +#include + +namespace bout { + +class OptionsIO { +public: + /// No default constructor, as settings are required + OptionsIO() = delete; + + /// Constructor specifies the kind of file, and options to control + /// the name of file, mode of operation etc. + OptionsIO(Options&) {} + + virtual ~OptionsIO() = default; + + OptionsIO(const OptionsIO&) = delete; + OptionsIO(OptionsIO&&) noexcept = default; + OptionsIO& operator=(const OptionsIO&) = delete; + OptionsIO& operator=(OptionsIO&&) noexcept = default; + + /// Read options from file + virtual Options read() = 0; + + /// Write options to file + void write(const Options& options) { write(options, "t"); } + virtual void write(const Options& options, const std::string& time_dim) = 0; + + /// NetCDF: Check that all variables with the same time dimension have the + /// same size in that dimension. Throws BoutException if there are + /// any differences, otherwise is silent. + /// ADIOS: Indicate completion of an output step. + virtual void verifyTimesteps() const = 0; + + /// Create an OptionsIO for I/O to the given file. + /// This uses the default file type and default options. + static std::unique_ptr create(const std::string& file); + + /// Create an OptionsIO for I/O to the given file. + /// The file will be configured using the given `config` options: + /// - "type" : string The file type e.g. "netcdf" or "adios" + /// - "file" : string Name of the file + /// - "append" : bool Append to existing data (Default is false) + static std::unique_ptr create(Options& config); + + /// Create an OptionsIO for I/O to the given file. + /// The file will be configured using the given `config` options: + /// - "type" : string The file type e.g. "netcdf" or "adios" + /// - "file" : string Name of the file + /// - "append" : bool Append to existing data (Default is false) + /// + /// Example: + /// + /// auto file = OptionsIO::create({ + /// {"file", "some_file.nc"}, + /// {"type", "netcdf"}, + /// {"append", false} + /// }); + static std::unique_ptr create(Options::InitializerList config_list) { + Options config(config_list); // Construct an Options to pass by reference + return create(config); + } +}; + +class OptionsIOFactory : public Factory { +public: + static constexpr auto type_name = "OptionsIO"; + static constexpr auto section_name = "io"; + static constexpr auto option_name = "type"; + static constexpr auto default_type = +#if BOUT_HAS_NETCDF + "netcdf"; +#elif BOUT_HAS_ADIOS2 + "adios"; +#else + "invalid"; +#endif + + /// Create a restart file, configured with options (if given), + /// or root "restart_files" section. + /// + /// Options: + /// - "type" The type of file e.g "netcdf" or "adios" + /// - "file" Name of the file. Default is /.[type-dependent] + /// - "path" Path to restart files. Default is root "datadir" option, + /// that defaults to "data" + /// - "prefix" Default is "BOUT.restart" + ReturnType createRestart(Options* optionsptr = nullptr) const; + + /// Create an output file for writing time history. + /// Configure with options (if given), or root "output" section. + /// + /// Options: + /// - "type" The type of file e.g "netcdf" or "adios" + /// - "file" Name of the file. Default is /.[type] + /// - "path" Path to output files. Default is root "datadir" option, + /// that defaults to "data" + /// - "prefix" Default is "BOUT.dmp" + /// - "append" Append to existing file? Default is root "append" option, + /// that defaults to false. + ReturnType createOutput(Options* optionsptr = nullptr) const; + + /// Create a single file (e.g. mesh file) of the default type + ReturnType createFile(const std::string& file) const; +}; + +/// Simpler name for Factory registration helper class +/// +/// Usage: +/// +/// #include +/// namespace { +/// RegisterOptionsIO registeroptionsiomine("myoptionsio"); +/// } +template +using RegisterOptionsIO = OptionsIOFactory::RegisterInFactory; + +/// Simpler name for indicating that an OptionsIO implementation +/// is unavailable. +/// +/// Usage: +/// +/// namespace { +/// RegisterUnavailableOptionsIO +/// unavailablemyoptionsio("myoptiosio", "BOUT++ was not configured with MyOptionsIO"); +/// } +using RegisterUnavailableOptionsIO = OptionsIOFactory::RegisterUnavailableInFactory; + +/// Convenient wrapper function around OptionsIOFactory::createOutput +/// Opens a dump file configured with the `output` root section, +/// and writes the given `data` to the file. +void writeDefaultOutputFile(Options& data); + +} // namespace bout + +#endif // OPTIONS_IO_H diff --git a/include/bout/options_netcdf.hxx b/include/bout/options_netcdf.hxx deleted file mode 100644 index 2fdb71c6d4..0000000000 --- a/include/bout/options_netcdf.hxx +++ /dev/null @@ -1,118 +0,0 @@ - -#pragma once - -#ifndef __OPTIONS_NETCDF_H__ -#define __OPTIONS_NETCDF_H__ - -#include "bout/build_config.hxx" - -#if !BOUT_HAS_NETCDF || BOUT_HAS_LEGACY_NETCDF - -#include - -#include "bout/boutexception.hxx" -#include "bout/options.hxx" - -namespace bout { - -class OptionsNetCDF { -public: - enum class FileMode { - replace, ///< Overwrite file when writing - append ///< Append to file when writing - }; - - OptionsNetCDF(const std::string& filename, FileMode mode = FileMode::replace) {} - OptionsNetCDF(const OptionsNetCDF&) = default; - OptionsNetCDF(OptionsNetCDF&&) = default; - OptionsNetCDF& operator=(const OptionsNetCDF&) = default; - OptionsNetCDF& operator=(OptionsNetCDF&&) = default; - - /// Read options from file - Options read() { throw BoutException("OptionsNetCDF not available\n"); } - - /// Write options to file - void write(const Options& options) { - throw BoutException("OptionsNetCDF not available\n"); - } -}; - -} // namespace bout - -#else - -#include -#include - -#include "bout/options.hxx" - -/// Forward declare netCDF file type so we don't need to depend -/// directly on netCDF -namespace netCDF { -class NcFile; -} - -namespace bout { - -class OptionsNetCDF { -public: - enum class FileMode { - replace, ///< Overwrite file when writing - append ///< Append to file when writing - }; - - // Constructors need to be defined in implementation due to forward - // declaration of NcFile - OptionsNetCDF(); - explicit OptionsNetCDF(std::string filename, FileMode mode = FileMode::replace); - ~OptionsNetCDF(); - OptionsNetCDF(const OptionsNetCDF&) = delete; - OptionsNetCDF(OptionsNetCDF&&) noexcept; - OptionsNetCDF& operator=(const OptionsNetCDF&) = delete; - OptionsNetCDF& operator=(OptionsNetCDF&&) noexcept; - - /// Read options from file - Options read(); - - /// Write options to file - void write(const Options& options) { write(options, "t"); } - void write(const Options& options, const std::string& time_dim); - - /// Check that all variables with the same time dimension have the - /// same size in that dimension. Throws BoutException if there are - /// any differences, otherwise is silent - void verifyTimesteps() const; - -private: - /// Name of the file on disk - std::string filename; - /// How to open the file for writing - FileMode file_mode{FileMode::replace}; - /// Pointer to netCDF file so we don't introduce direct dependence - std::unique_ptr data_file; -}; - -} // namespace bout - -#endif - -namespace bout { -/// Name of the directory for restart files -std::string getRestartDirectoryName(Options& options); -/// Name of the restart file on this rank -std::string getRestartFilename(Options& options); -/// Name of the restart file on \p rank -std::string getRestartFilename(Options& options, int rank); -/// Name of the main output file on this rank -std::string getOutputFilename(Options& options); -/// Name of the main output file on \p rank -std::string getOutputFilename(Options& options, int rank); -/// Write `Options::root()` to the main output file, overwriting any -/// existing files -void writeDefaultOutputFile(); -/// Write \p options to the main output file, overwriting any existing -/// files -void writeDefaultOutputFile(Options& options); -} // namespace bout - -#endif // __OPTIONS_NETCDF_H__ diff --git a/include/bout/optionsreader.hxx b/include/bout/optionsreader.hxx index 428c7a8c8f..de3d40514d 100644 --- a/include/bout/optionsreader.hxx +++ b/include/bout/optionsreader.hxx @@ -31,10 +31,9 @@ class OptionsReader; -#ifndef __OPTIONSREADER_H__ -#define __OPTIONSREADER_H__ +#ifndef BOUT_OPTIONSREADER_H +#define BOUT_OPTIONSREADER_H -#include "bout/format.hxx" #include "bout/options.hxx" #include "fmt/core.h" @@ -109,4 +108,4 @@ private: static OptionsReader* instance; }; -#endif // __OPTIONSREADER_H__ +#endif // BOUT_OPTIONSREADER_H diff --git a/include/bout/output.hxx b/include/bout/output.hxx index ef09aa7ee5..2862899067 100644 --- a/include/bout/output.hxx +++ b/include/bout/output.hxx @@ -26,8 +26,8 @@ class Output; #pragma once -#ifndef __OUTPUT_H__ -#define __OUTPUT_H__ +#ifndef BOUT_OUTPUT_H +#define BOUT_OUTPUT_H #include "bout/multiostream.hxx" #include @@ -37,7 +37,6 @@ class Output; #include "bout/assert.hxx" #include "bout/boutexception.hxx" -#include "bout/format.hxx" #include "bout/sys/gettext.hxx" // for gettext _() macro #include "bout/unused.hxx" @@ -144,7 +143,7 @@ public: void print([[maybe_unused]] const std::string& message) override{}; void enable() override{}; void disable() override{}; - void enable(MAYBE_UNUSED(bool enable)){}; + void enable([[maybe_unused]] bool enable){}; bool isEnabled() override { return false; } }; @@ -305,4 +304,4 @@ extern ConditionalOutput output_verbose; ///< less interesting messages /// Generic output, given the same level as output_progress extern ConditionalOutput output; -#endif // __OUTPUT_H__ +#endif // BOUT_OUTPUT_H diff --git a/include/bout/output_bout_types.hxx b/include/bout/output_bout_types.hxx index 6b1829b088..b67762521b 100644 --- a/include/bout/output_bout_types.hxx +++ b/include/bout/output_bout_types.hxx @@ -34,7 +34,7 @@ struct fmt::formatter> { // Formats the point p using the parsed format specification (presentation) // stored in this formatter. template - auto format(const SpecificInd& ind, FormatContext& ctx) { + auto format(const SpecificInd& ind, FormatContext& ctx) const { // ctx.out() is an output iterator to write to. if (presentation == 'c') { switch (N) { diff --git a/include/bout/parallel_boundary_op.hxx b/include/bout/parallel_boundary_op.hxx index 8b1fc8098f..d8620e892b 100644 --- a/include/bout/parallel_boundary_op.hxx +++ b/include/bout/parallel_boundary_op.hxx @@ -1,8 +1,9 @@ -#ifndef __PAR_BNDRY_OP_H__ -#define __PAR_BNDRY_OP_H__ +#ifndef BOUT_PAR_BNDRY_OP_H +#define BOUT_PAR_BNDRY_OP_H #include "bout/boundary_op.hxx" #include "bout/bout_types.hxx" +#include "bout/field_factory.hxx" #include "bout/parallel_boundary_region.hxx" #include "bout/unused.hxx" #include "bout/utils.hxx" @@ -21,17 +22,14 @@ public: : bndry(region), field_values(value), value_type(ValueType::FIELD) {} BoundaryOpPar(BoundaryRegionPar* region, BoutReal value) : bndry(region), real_value(value), value_type(ValueType::REAL) {} + BoundaryOpPar(BoundaryRegionPar* region) + : bndry(region), real_value(0.), value_type(ValueType::REAL) {} ~BoundaryOpPar() override = default; // Note: All methods must implement clone, except for modifiers (see below) - virtual BoundaryOpPar* clone(BoundaryRegionPar* UNUSED(region), - const std::list& UNUSED(args)) { - return nullptr; - } - virtual BoundaryOpPar* clone(BoundaryRegionPar* UNUSED(region), Field3D* UNUSED(f)) { - return nullptr; - } - + virtual BoundaryOpPar* clone(BoundaryRegionPar* region, + const std::list& args) = 0; + virtual BoundaryOpPar* clone(BoundaryRegionPar* region, Field3D* f) = 0; virtual BoundaryOpPar* clone(BoundaryRegionPar* region, const std::list& args, const std::map& UNUSED(keywords)) { @@ -39,118 +37,126 @@ public: return clone(region, args); } - using BoundaryOpBase::apply; - void apply(Field2D& UNUSED(f)) override { - throw BoutException("Can't apply parallel boundary conditions to Field2D!"); - } - void apply(Field2D& UNUSED(f), BoutReal UNUSED(t)) override { - throw BoutException("Can't apply parallel boundary conditions to Field2D!"); - } - BoundaryRegionPar* bndry{nullptr}; protected: /// Possible ways to get boundary values std::shared_ptr gen_values; - Field3D* field_values; + Field3D* field_values{nullptr}; BoutReal real_value{0.}; /// Where to take boundary values from - the generator, field or BoutReal enum class ValueType { GEN, FIELD, REAL }; const ValueType value_type{ValueType::REAL}; - BoutReal getValue(int x, int y, int z, BoutReal t); BoutReal getValue(const BoundaryRegionPar& bndry, BoutReal t); }; -////////////////////////////////////////////////// -// Implementations - -class BoundaryOpPar_dirichlet : public BoundaryOpPar { +template +class BoundaryOpParTemp : public BoundaryOpPar { public: - BoundaryOpPar_dirichlet() : BoundaryOpPar(nullptr, 0.) {} - BoundaryOpPar_dirichlet(BoundaryRegionPar* region) : BoundaryOpPar(region, 0.) {} - BoundaryOpPar_dirichlet(BoundaryRegionPar* region, - std::shared_ptr value) - : BoundaryOpPar(region, value) {} - BoundaryOpPar_dirichlet(BoundaryRegionPar* region, Field3D* value) - : BoundaryOpPar(region, value) {} - BoundaryOpPar_dirichlet(BoundaryRegionPar* region, BoutReal value) - : BoundaryOpPar(region, value) {} + using BoundaryOpPar::BoundaryOpPar; using BoundaryOpPar::clone; + + // Note: All methods must implement clone, except for modifiers (see below) BoundaryOpPar* clone(BoundaryRegionPar* region, - const std::list& args) override; - BoundaryOpPar* clone(BoundaryRegionPar* region, Field3D* f) override; + const std::list& args) override { + if (!args.empty()) { + try { + real_value = stringToReal(args.front()); + return new T(region, real_value); + } catch (const BoutException&) { + std::shared_ptr newgen = nullptr; + // First argument should be an expression + newgen = FieldFactory::get()->parse(args.front()); + return new T(region, newgen); + } + } + + return new T(region); + } + + BoundaryOpPar* clone(BoundaryRegionPar* region, Field3D* f) override { + return new T(region, f); + } - using BoundaryOpPar::apply; + using BoundaryOpBase::apply; + void apply(Field2D& UNUSED(f)) final { + throw BoutException("Can't apply parallel boundary conditions to Field2D!"); + } + void apply(Field2D& UNUSED(f), BoutReal UNUSED(t)) final { + throw BoutException("Can't apply parallel boundary conditions to Field2D!"); + } void apply(Field3D& f) override { return apply(f, 0); } - void apply(Field3D& f, BoutReal t) override; -}; -class BoundaryOpPar_dirichlet_O3 : public BoundaryOpPar { -public: - BoundaryOpPar_dirichlet_O3() : BoundaryOpPar(nullptr, 0.) {} - BoundaryOpPar_dirichlet_O3(BoundaryRegionPar* region) : BoundaryOpPar(region, 0.) {} - BoundaryOpPar_dirichlet_O3(BoundaryRegionPar* region, - std::shared_ptr value) - : BoundaryOpPar(region, value) {} - BoundaryOpPar_dirichlet_O3(BoundaryRegionPar* region, Field3D* value) - : BoundaryOpPar(region, value) {} - BoundaryOpPar_dirichlet_O3(BoundaryRegionPar* region, BoutReal value) - : BoundaryOpPar(region, value) {} + void apply(Field3D& f, BoutReal t) override { + f.ynext(bndry->dir).allocate(); // Ensure unique before modifying - using BoundaryOpPar::clone; - BoundaryOpPar* clone(BoundaryRegionPar* region, - const std::list& args) override; - BoundaryOpPar* clone(BoundaryRegionPar* region, Field3D* f) override; + auto dy = f.getCoordinates()->dy; - using BoundaryOpPar::apply; - void apply(Field3D& f) override { return apply(f, 0); } - void apply(Field3D& f, BoutReal t) override; + for (bndry->first(); !bndry->isDone(); bndry->next()) { + BoutReal value = getValue(*bndry, t); + if (isNeumann) { + value *= dy[bndry->ind()]; + } + static_cast(this)->apply_stencil(f, bndry, value); + } + } }; -class BoundaryOpPar_dirichlet_interp : public BoundaryOpPar { +////////////////////////////////////////////////// +// Implementations + +class BoundaryOpPar_dirichlet_o1 : public BoundaryOpParTemp { public: - BoundaryOpPar_dirichlet_interp() : BoundaryOpPar(nullptr, 0.) {} - BoundaryOpPar_dirichlet_interp(BoundaryRegionPar* region) : BoundaryOpPar(region, 0.) {} - BoundaryOpPar_dirichlet_interp(BoundaryRegionPar* region, - std::shared_ptr value) - : BoundaryOpPar(region, value) {} - BoundaryOpPar_dirichlet_interp(BoundaryRegionPar* region, Field3D* value) - : BoundaryOpPar(region, value) {} - BoundaryOpPar_dirichlet_interp(BoundaryRegionPar* region, BoutReal value) - : BoundaryOpPar(region, value) {} + using BoundaryOpParTemp::BoundaryOpParTemp; + static void apply_stencil(Field3D& f, const BoundaryRegionPar* bndry, BoutReal value) { + bndry->dirichlet_o1(f, value); + } +}; - using BoundaryOpPar::clone; - BoundaryOpPar* clone(BoundaryRegionPar* region, - const std::list& args) override; - BoundaryOpPar* clone(BoundaryRegionPar* region, Field3D* f) override; +class BoundaryOpPar_dirichlet_o2 : public BoundaryOpParTemp { +public: + using BoundaryOpParTemp::BoundaryOpParTemp; + static void apply_stencil(Field3D& f, const BoundaryRegionPar* bndry, BoutReal value) { + bndry->dirichlet_o2(f, value); + } +}; - using BoundaryOpPar::apply; - void apply(Field3D& f) override { return apply(f, 0); } - void apply(Field3D& f, BoutReal t) override; +class BoundaryOpPar_dirichlet_o3 : public BoundaryOpParTemp { +public: + using BoundaryOpParTemp::BoundaryOpParTemp; + static void apply_stencil(Field3D& f, const BoundaryRegionPar* bndry, BoutReal value) { + bndry->dirichlet_o3(f, value); + } }; -class BoundaryOpPar_neumann : public BoundaryOpPar { +class BoundaryOpPar_neumann_o1 + : public BoundaryOpParTemp { public: - BoundaryOpPar_neumann() : BoundaryOpPar(nullptr, 0.) {} - BoundaryOpPar_neumann(BoundaryRegionPar* region) : BoundaryOpPar(region, 0.) {} - BoundaryOpPar_neumann(BoundaryRegionPar* region, std::shared_ptr value) - : BoundaryOpPar(region, value) {} - BoundaryOpPar_neumann(BoundaryRegionPar* region, Field3D* value) - : BoundaryOpPar(region, value) {} - BoundaryOpPar_neumann(BoundaryRegionPar* region, BoutReal value) - : BoundaryOpPar(region, value) {} + using BoundaryOpParTemp::BoundaryOpParTemp; + static void apply_stencil(Field3D& f, const BoundaryRegionPar* bndry, BoutReal value) { + bndry->neumann_o1(f, value); + } +}; - using BoundaryOpPar::clone; - BoundaryOpPar* clone(BoundaryRegionPar* region, - const std::list& args) override; - BoundaryOpPar* clone(BoundaryRegionPar* region, Field3D* f) override; +class BoundaryOpPar_neumann_o2 + : public BoundaryOpParTemp { +public: + using BoundaryOpParTemp::BoundaryOpParTemp; + static void apply_stencil(Field3D& f, const BoundaryRegionPar* bndry, BoutReal value) { + bndry->neumann_o2(f, value); + } +}; - using BoundaryOpPar::apply; - void apply(Field3D& f) override { return apply(f, 0); } - void apply(Field3D& f, BoutReal t) override; +class BoundaryOpPar_neumann_o3 + : public BoundaryOpParTemp { +public: + using BoundaryOpParTemp::BoundaryOpParTemp; + static void apply_stencil(Field3D& f, const BoundaryRegionPar* bndry, BoutReal value) { + bndry->neumann_o3(f, value); + } }; -#endif // __PAR_BNDRY_OP_H__ +#endif // BOUT_PAR_BNDRY_OP_H diff --git a/include/bout/parallel_boundary_region.hxx b/include/bout/parallel_boundary_region.hxx index 3d5525a303..308b5ac5d7 100644 --- a/include/bout/parallel_boundary_region.hxx +++ b/include/bout/parallel_boundary_region.hxx @@ -1,22 +1,58 @@ -#ifndef __PAR_BNDRY_H__ -#define __PAR_BNDRY_H__ +#ifndef BOUT_PAR_BNDRY_H +#define BOUT_PAR_BNDRY_H #include "bout/boundary_region.hxx" #include "bout/bout_types.hxx" #include +#include +#include + /** * Boundary region for parallel direction. This contains a vector of points that are * inside the boundary. * */ -class BoundaryRegionPar : public BoundaryRegionBase { - struct IndexPoint { - int jx; - int jy; - int jz; - }; +namespace parallel_stencil { +// generated by src/mesh/parallel_boundary_stencil.cxx.py +inline BoutReal pow(BoutReal val, int exp) { + // constexpr int expval = exp; + // static_assert(expval == 2 or expval == 3, "This pow is only for exponent 2 or 3"); + if (exp == 2) { + return val * val; + } + ASSERT3(exp == 3); + return val * val * val; +} +inline BoutReal dirichlet_o1(BoutReal UNUSED(spacing0), BoutReal value0) { + return value0; +} +inline BoutReal dirichlet_o2(BoutReal spacing0, BoutReal value0, BoutReal spacing1, + BoutReal value1) { + return (spacing0 * value1 - spacing1 * value0) / (spacing0 - spacing1); +} +inline BoutReal neumann_o2(BoutReal UNUSED(spacing0), BoutReal value0, BoutReal spacing1, + BoutReal value1) { + return -spacing1 * value0 + value1; +} +inline BoutReal dirichlet_o3(BoutReal spacing0, BoutReal value0, BoutReal spacing1, + BoutReal value1, BoutReal spacing2, BoutReal value2) { + return (pow(spacing0, 2) * spacing1 * value2 - pow(spacing0, 2) * spacing2 * value1 + - spacing0 * pow(spacing1, 2) * value2 + spacing0 * pow(spacing2, 2) * value1 + + pow(spacing1, 2) * spacing2 * value0 - spacing1 * pow(spacing2, 2) * value0) + / ((spacing0 - spacing1) * (spacing0 - spacing2) * (spacing1 - spacing2)); +} +inline BoutReal neumann_o3(BoutReal spacing0, BoutReal value0, BoutReal spacing1, + BoutReal value1, BoutReal spacing2, BoutReal value2) { + return (2 * spacing0 * spacing1 * value2 - 2 * spacing0 * spacing2 * value1 + + pow(spacing1, 2) * spacing2 * value0 - pow(spacing1, 2) * value2 + - spacing1 * pow(spacing2, 2) * value0 + pow(spacing2, 2) * value1) + / ((spacing1 - spacing2) * (2 * spacing0 - spacing1 - spacing2)); +} +} // namespace parallel_stencil + +class BoundaryRegionPar : public BoundaryRegionBase { struct RealPoint { BoutReal s_x; @@ -26,13 +62,15 @@ class BoundaryRegionPar : public BoundaryRegionBase { struct Indices { // Indices of the boundary point - IndexPoint index; + Ind3D index; // Intersection with boundary in index space RealPoint intersection; // Distance to intersection BoutReal length; // Angle between field line and boundary - BoutReal angle; + // BoutReal angle; + // How many points we can go in the opposite direction + signed char valid; }; using IndicesVec = std::vector; @@ -46,28 +84,122 @@ class BoundaryRegionPar : public BoundaryRegionBase { public: BoundaryRegionPar(const std::string& name, int dir, Mesh* passmesh) : BoundaryRegionBase(name, passmesh), dir(dir) { + ASSERT0(std::abs(dir) == 1); BoundaryRegionBase::isParallel = true; } BoundaryRegionPar(const std::string& name, BndryLoc loc, int dir, Mesh* passmesh) : BoundaryRegionBase(name, loc, passmesh), dir(dir) { BoundaryRegionBase::isParallel = true; + ASSERT0(std::abs(dir) == 1); } /// Add a point to the boundary - void add_point(int jx, int jy, int jz, BoutReal x, BoutReal y, BoutReal z, - BoutReal length, BoutReal angle); + void add_point(Ind3D ind, BoutReal x, BoutReal y, BoutReal z, BoutReal length, + char valid) { + bndry_points.push_back({ind, {x, y, z}, length, valid}); + } + void add_point(int ix, int iy, int iz, BoutReal x, BoutReal y, BoutReal z, + BoutReal length, char valid) { + bndry_points.push_back({xyz2ind(ix, iy, iz, localmesh), {x, y, z}, length, valid}); + } + + // final, so they can be inlined + void first() final { bndry_position = begin(bndry_points); } + void next() final { ++bndry_position; } + bool isDone() final { return (bndry_position == end(bndry_points)); } - void first() override; - void next() override; - bool isDone() override; + // getter + Ind3D ind() const { return bndry_position->index; } + BoutReal s_x() const { return bndry_position->intersection.s_x; } + BoutReal s_y() const { return bndry_position->intersection.s_y; } + BoutReal s_z() const { return bndry_position->intersection.s_z; } + BoutReal length() const { return bndry_position->length; } + char valid() const { return bndry_position->valid; } - /// Index of the point in the boundary - int x, y, z; - BoutReal s_x, s_y, s_z; - BoutReal length; - BoutReal angle; + // setter + void setValid(char val) { bndry_position->valid = val; } + + bool contains(const BoundaryRegionPar& bndry) const { + return std::binary_search( + begin(bndry_points), end(bndry_points), *bndry.bndry_position, + [](const Indices& i1, const Indices& i2) { return i1.index < i2.index; }); + } + + // extrapolate a given point to the boundary + BoutReal extrapolate_o1(const Field3D& f) const { return f[ind()]; } + BoutReal extrapolate_o2(const Field3D& f) const { + ASSERT3(valid() >= 0); + if (valid() < 1) { + return extrapolate_o1(f); + } + return f[ind()] * (1 + length()) - f.ynext(-dir)[ind().yp(-dir)] * length(); + } + + // dirichlet boundary code + void dirichlet_o1(Field3D& f, BoutReal value) const { + f.ynext(dir)[ind().yp(dir)] = value; + } + + void dirichlet_o2(Field3D& f, BoutReal value) const { + if (length() < small_value) { + return dirichlet_o1(f, value); + } + ynext(f) = parallel_stencil::dirichlet_o2(1, f[ind()], 1 - length(), value); + // ynext(f) = f[ind()] * (1 + 1/length()) + value / length(); + } + + void dirichlet_o3(Field3D& f, BoutReal value) const { + ASSERT3(valid() >= 0); + if (valid() < 1) { + return dirichlet_o2(f, value); + } + if (length() < small_value) { + ynext(f) = parallel_stencil::dirichlet_o2(2, yprev(f), 1 - length(), value); + } else { + ynext(f) = + parallel_stencil::dirichlet_o3(2, yprev(f), 1, f[ind()], 1 - length(), value); + } + } + + // NB: value needs to be scaled by dy + // neumann_o1 is actually o2 if we would use an appropriate one-sided stencil. + // But in general we do not, and thus for normal C2 stencils, this is 1st order. + void neumann_o1(Field3D& f, BoutReal value) const { ynext(f) = f[ind()] + value; } + + // NB: value needs to be scaled by dy + void neumann_o2(Field3D& f, BoutReal value) const { + ASSERT3(valid() >= 0); + if (valid() < 1) { + return neumann_o1(f, value); + } + ynext(f) = yprev(f) + 2 * value; + } + + // NB: value needs to be scaled by dy + void neumann_o3(Field3D& f, BoutReal value) const { + ASSERT3(valid() >= 0); + if (valid() < 1) { + return neumann_o1(f, value); + } + ynext(f) = + parallel_stencil::neumann_o3(1 - length(), value, 1, f[ind()], 2, yprev(f)); + } const int dir; + +private: + constexpr static BoutReal small_value = 1e-2; + + // BoutReal get(const Field3D& f, int off) + const BoutReal& ynext(const Field3D& f) const { return f.ynext(dir)[ind().yp(dir)]; } + BoutReal& ynext(Field3D& f) const { return f.ynext(dir)[ind().yp(dir)]; } + const BoutReal& yprev(const Field3D& f) const { return f.ynext(-dir)[ind().yp(-dir)]; } + BoutReal& yprev(Field3D& f) const { return f.ynext(-dir)[ind().yp(-dir)]; } + static Ind3D xyz2ind(int x, int y, int z, Mesh* mesh) { + const int ny = mesh->LocalNy; + const int nz = mesh->LocalNz; + return Ind3D{(x * ny + y) * nz + z, ny, nz}; + } }; -#endif // __PAR_BNDRY_H__ +#endif // BOUT_PAR_BNDRY_H diff --git a/include/bout/paralleltransform.hxx b/include/bout/paralleltransform.hxx index bb00dcbd45..0aafa04303 100644 --- a/include/bout/paralleltransform.hxx +++ b/include/bout/paralleltransform.hxx @@ -3,8 +3,8 @@ * values along Y */ -#ifndef __PARALLELTRANSFORM_H__ -#define __PARALLELTRANSFORM_H__ +#ifndef BOUT_PARALLELTRANSFORM_H +#define BOUT_PARALLELTRANSFORM_H #include "bout/bout_types.hxx" #include "bout/field3d.hxx" @@ -83,7 +83,7 @@ public: } /// Output variables used by a ParallelTransform instance to \p output_options - virtual void outputVars(MAYBE_UNUSED(Options& output_options)) {} + virtual void outputVars([[maybe_unused]] Options& output_options) {} /// If \p twist_shift_enabled is true, does a `Field3D` with Y direction \p ytype /// require a twist-shift at branch cuts on closed field lines? @@ -317,4 +317,4 @@ private: const std::vector& phases) const; }; -#endif // __PARALLELTRANSFORM_H__ +#endif // BOUT_PARALLELTRANSFORM_H diff --git a/include/bout/petsc_interface.hxx b/include/bout/petsc_interface.hxx index 8e7d44c67d..407e5ac18e 100644 --- a/include/bout/petsc_interface.hxx +++ b/include/bout/petsc_interface.hxx @@ -27,13 +27,18 @@ * **************************************************************************/ -#ifndef __PETSC_INTERFACE_H__ -#define __PETSC_INTERFACE_H__ +#ifndef BOUT_PETSC_INTERFACE_H +#define BOUT_PETSC_INTERFACE_H #include "bout/build_config.hxx" +#if BOUT_HAS_PETSC + #include +#include #include +#include +#include #include #include @@ -47,8 +52,6 @@ #include #include -#if BOUT_HAS_PETSC - /*! * A class which wraps PETSc vector objects, allowing them to be * indexed using the BOUT++ scheme. Note that boundaries are only @@ -59,167 +62,103 @@ class PetscVector; template void swap(PetscVector& first, PetscVector& second); +template +inline MPI_Comm getComm([[maybe_unused]] const T& field) { + return BoutComm::get(); +} + +template <> +inline MPI_Comm getComm([[maybe_unused]] const FieldPerp& field) { + return field.getMesh()->getXcomm(); +} + template class PetscVector { public: - static_assert(bout::utils::is_Field::value, "PetscVector only works with Fields"); + static_assert(bout::utils::is_Field_v, "PetscVector only works with Fields"); using ind_type = typename T::ind_type; struct VectorDeleter { - void operator()(Vec* v) const { - VecDestroy(v); - delete v; + void operator()(Vec* vec) const { + VecDestroy(vec); + delete vec; } }; - /// Default constructor does nothing - PetscVector() : vector(new Vec(), VectorDeleter()) {} + PetscVector() : vector(new Vec{}) {} + ~PetscVector() = default; - /// Copy constructor - PetscVector(const PetscVector& v) : vector(new Vec(), VectorDeleter()) { - VecDuplicate(*v.vector, vector.get()); - VecCopy(*v.vector, *vector); - indexConverter = v.indexConverter; - location = v.location; - initialised = v.initialised; + PetscVector(const PetscVector& vec) + : vector(new Vec()), indexConverter(vec.indexConverter), location(vec.location), + initialised(vec.initialised), vector_values(vec.vector_values) { + VecDuplicate(*vec.vector, vector.get()); + VecCopy(*vec.vector, *vector); } - /// Move constrcutor - PetscVector(PetscVector&& v) { - std::swap(vector, v.vector); - indexConverter = v.indexConverter; - location = v.location; - initialised = v.initialised; - v.initialised = false; + PetscVector(PetscVector&& vec) noexcept + : indexConverter(vec.indexConverter), location(vec.location), + initialised(vec.initialised), vector_values(std::move(vec.vector_values)) { + std::swap(vector, vec.vector); + vec.initialised = false; } /// Construct from a field, copying over the field values - PetscVector(const T& f, IndexerPtr indConverter) - : vector(new Vec(), VectorDeleter()), indexConverter(indConverter) { - ASSERT1(indConverter->getMesh() == f.getMesh()); - const MPI_Comm comm = - std::is_same::value ? f.getMesh()->getXcomm() : BoutComm::get(); + PetscVector(const T& field, IndexerPtr indConverter) + : vector(new Vec()), indexConverter(indConverter), location(field.getLocation()), + initialised(true), vector_values(field.size()) { + ASSERT1(indConverter->getMesh() == field.getMesh()); + MPI_Comm comm = getComm(field); + const int size = indexConverter->size(); VecCreateMPI(comm, size, PETSC_DECIDE, vector.get()); - location = f.getLocation(); - initialised = true; - *this = f; + // This allows us to pass negative indices + VecSetOption(*vector, VEC_IGNORE_NEGATIVE_INDICES, PETSC_TRUE); + *this = field; } /// Construct a vector like v, but using data from a raw PETSc /// Vec. That Vec (not a copy) will then be owned by the new object. - PetscVector(const PetscVector& v, Vec* vec) { + PetscVector(const PetscVector& other, Vec* vec) { #if CHECKLEVEL >= 2 - int fsize = v.indexConverter->size(), msize; + int fsize = other.indexConverter->size(); + int msize = 0; VecGetLocalSize(*vec, &msize); ASSERT2(fsize == msize); #endif vector.reset(vec); - indexConverter = v.indexConverter; - location = v.location; + indexConverter = other.indexConverter; + location = other.location; initialised = true; } /// Copy assignment PetscVector& operator=(const PetscVector& rhs) { - return *this = PetscVector(rhs); + *this = PetscVector(rhs); + return *this; } /// Move assignment - PetscVector& operator=(PetscVector&& rhs) { + PetscVector& operator=(PetscVector&& rhs) noexcept { swap(*this, rhs); return *this; } - PetscVector& operator=(const T& f) { + PetscVector& operator=(const T& field) { ASSERT1(indexConverter); // Needs to have index set - BOUT_FOR_SERIAL(i, indexConverter->getRegionAll()) { - const PetscInt ind = indexConverter->getGlobal(i); - if (ind != -1) { - // TODO: consider how VecSetValues() could be used where there - // are continuous stretches of field data which should be - // copied into the vector. - VecSetValue(*vector, ind, f[i], INSERT_VALUES); - } - } + BOUT_FOR_SERIAL(i, indexConverter->getRegionAll()) { (*this)(i) = field[i]; } assemble(); return *this; } friend void swap(PetscVector& first, PetscVector& second); - /*! - * A class which is used to assign to a particular element of a PETSc - * vector. It is meant to be transient and will be destroyed immediately - * after use. In general you should not try to assign an instance to a - * variable. - * - * The Element object will store a copy of the value which has been - * assigned to it. This is because mixing calls to the PETSc - * function VecGetValues() and VecSetValues() without intermediate - * vector assembly will cause errors. Thus, if the user wishes to - * get the value of the vector, it must be stored here. - */ - class Element { - public: - Element() = delete; - Element(const Element& other) = default; - Element(Vec* vector, int index) : petscVector(vector), petscIndex(index) { - int status; - BOUT_OMP(critical) - status = VecGetValues(*petscVector, 1, &petscIndex, &value); - if (status != 0) { - value = 0.; - } - } - Element& operator=(const Element& other) { - ASSERT3(finite(static_cast(other))); - return *this = static_cast(other); - } - Element& operator=(BoutReal val) { - ASSERT3(finite(val)); - value = val; - int status; - BOUT_OMP(critical) - status = VecSetValue(*petscVector, petscIndex, val, INSERT_VALUES); - if (status != 0) { - throw BoutException("Error when setting elements of a PETSc vector."); - } - return *this; - } - Element& operator+=(BoutReal val) { - ASSERT3(finite(val)); - value += val; - ASSERT3(finite(value)); - int status; - BOUT_OMP(critical) - status = VecSetValue(*petscVector, petscIndex, val, ADD_VALUES); - if (status != 0) { - throw BoutException("Error when setting elements of a PETSc vector."); - } - return *this; - } - operator BoutReal() const { return value; } - - private: - Vec* petscVector = nullptr; - PetscInt petscIndex; - PetscScalar value; - }; - - Element operator()(const ind_type& index) { + BoutReal& operator()(const ind_type& index) { #if CHECKLEVEL >= 1 if (!initialised) { throw BoutException("Can not return element of uninitialised vector"); } #endif - const int global = indexConverter->getGlobal(index); -#if CHECKLEVEL >= 1 - if (global == -1) { - throw BoutException("Request to return invalid vector element"); - } -#endif - return Element(vector.get(), global); + return vector_values[index.ind]; } BoutReal operator()(const ind_type& index) const { @@ -234,9 +173,9 @@ public: throw BoutException("Request to return invalid vector element"); } #endif - BoutReal value; - int status; - BOUT_OMP(critical) + BoutReal value = BoutNaN; + int status = 0; + BOUT_OMP_SAFE(critical) status = VecGetValues(*get(), 1, &global, &value); if (status != 0) { throw BoutException("Error when getting element of a PETSc vector."); @@ -245,8 +184,21 @@ public: } void assemble() { - VecAssemblyBegin(*vector); - VecAssemblyEnd(*vector); + auto ierr = VecSetValues(*vector, vector_values.size(), + indexConverter->getIntIndices().begin(), + vector_values.begin(), INSERT_VALUES); + if (ierr < 0) { + throw BoutException("PETSc error"); + } + + ierr = VecAssemblyBegin(*vector); + if (ierr < 0) { + throw BoutException("PETSc error"); + } + ierr = VecAssemblyEnd(*vector); + if (ierr < 0) { + throw BoutException("PETSc error"); + } } void destroy() { @@ -264,8 +216,8 @@ public: result.setLocation(location); // Note that this only populates boundaries to a depth of 1 BOUT_FOR_SERIAL(i, indexConverter->getRegionAll()) { - PetscInt ind = indexConverter->getGlobal(i); - PetscScalar val; + const PetscInt ind = indexConverter->getGlobal(i); + PetscScalar val = BoutNaN; VecGetValues(*vector, 1, &ind, &val); result[i] = val; } @@ -277,11 +229,12 @@ public: const Vec* get() const { return vector.get(); } private: - PetscLib lib; + PetscLib lib{}; std::unique_ptr vector = nullptr; - IndexerPtr indexConverter; - CELL_LOC location; + IndexerPtr indexConverter{}; + CELL_LOC location = CELL_LOC::deflt; bool initialised = false; + Array vector_values{}; }; /*! @@ -297,44 +250,41 @@ void swap(PetscMatrix& first, PetscMatrix& second); template class PetscMatrix { public: - static_assert(bout::utils::is_Field::value, "PetscMatrix only works with Fields"); + static_assert(bout::utils::is_Field_v, "PetscMatrix only works with Fields"); using ind_type = typename T::ind_type; struct MatrixDeleter { - void operator()(Mat* m) const { - MatDestroy(m); - delete m; + void operator()(Mat* mat) const { + MatDestroy(mat); + delete mat; } }; /// Default constructor does nothing - PetscMatrix() : matrix(new Mat(), MatrixDeleter()) {} + PetscMatrix() : matrix(new Mat()) {} + ~PetscMatrix() = default; /// Copy constructor - PetscMatrix(const PetscMatrix& m) : matrix(new Mat(), MatrixDeleter()), pt(m.pt) { - MatDuplicate(*m.matrix, MAT_COPY_VALUES, matrix.get()); - indexConverter = m.indexConverter; - yoffset = m.yoffset; - initialised = m.initialised; + PetscMatrix(const PetscMatrix& mat) + : matrix(new Mat()), indexConverter(mat.indexConverter), pt(mat.pt), + yoffset(mat.yoffset), initialised(mat.initialised) { + MatDuplicate(*mat.matrix, MAT_COPY_VALUES, matrix.get()); } /// Move constrcutor - PetscMatrix(PetscMatrix&& m) : pt(m.pt) { - matrix = m.matrix; - indexConverter = m.indexConverter; - yoffset = m.yoffset; - initialised = m.initialised; - m.initialised = false; + PetscMatrix(PetscMatrix&& mat) noexcept + : matrix(std::move(mat.matrix)), indexConverter(std::move(mat.indexConverter)), + pt(mat.pt), yoffset(mat.yoffset), initialised(mat.initialised) { + mat.initialised = false; } // Construct a matrix capable of operating on the specified field, // preallocating memory if requeted and possible. PetscMatrix(IndexerPtr indConverter, bool preallocate = true) - : matrix(new Mat(), MatrixDeleter()), indexConverter(indConverter) { - const MPI_Comm comm = std::is_same::value - ? indConverter->getMesh()->getXcomm() - : BoutComm::get(); - pt = &indConverter->getMesh()->getCoordinates()->getParallelTransform(); + : matrix(new Mat()), indexConverter(indConverter), + pt(&indConverter->getMesh()->getCoordinates()->getParallelTransform()) { + MPI_Comm comm = std::is_same_v ? indConverter->getMesh()->getXcomm() + : BoutComm::get(); const int size = indexConverter->size(); MatCreate(comm, matrix.get()); @@ -358,7 +308,7 @@ public: return *this; } /// Move assignment - PetscMatrix& operator=(PetscMatrix&& rhs) { + PetscMatrix& operator=(PetscMatrix&& rhs) noexcept { matrix = rhs.matrix; indexConverter = rhs.indexConverter; pt = rhs.pt; @@ -384,24 +334,28 @@ public: class Element { public: Element() = delete; + ~Element() = default; + Element(Element&&) noexcept = default; + Element& operator=(Element&&) noexcept = default; Element(const Element& other) = default; - Element(Mat* matrix, PetscInt row, PetscInt col, std::vector p = {}, - std::vector w = {}) - : petscMatrix(matrix), petscRow(row), petscCol(col), positions(p), weights(w) { + Element(Mat* matrix, PetscInt row, PetscInt col, std::vector position = {}, + std::vector weight = {}) + : petscMatrix(matrix), petscRow(row), petscCol(col), + positions(std::move(position)), weights(std::move(weight)) { ASSERT2(positions.size() == weights.size()); #if CHECK > 2 for (const auto val : weights) { ASSERT3(finite(val)); } #endif - if (positions.size() == 0) { + if (positions.empty()) { positions = {col}; weights = {1.0}; } - PetscBool assembled; + PetscBool assembled = PETSC_FALSE; MatAssembled(*petscMatrix, &assembled); if (assembled == PETSC_TRUE) { - BOUT_OMP(critical) + BOUT_OMP_SAFE(critical) MatGetValues(*petscMatrix, 1, &petscRow, 1, &petscCol, &value); } else { value = 0.; @@ -409,8 +363,12 @@ public: } Element& operator=(const Element& other) { AUTO_TRACE(); + if (this == &other) { + return *this; + } ASSERT3(finite(static_cast(other))); - return *this = static_cast(other); + *this = static_cast(other); + return *this; } Element& operator=(BoutReal val) { AUTO_TRACE(); @@ -424,8 +382,8 @@ public: ASSERT3(finite(val)); auto columnPosition = std::find(positions.begin(), positions.end(), petscCol); if (columnPosition != positions.end()) { - int i = std::distance(positions.begin(), columnPosition); - value += weights[i] * val; + const int index = std::distance(positions.begin(), columnPosition); + value += weights[index] * val; ASSERT3(finite(value)); } setValues(val, ADD_VALUES); @@ -441,8 +399,8 @@ public: std::transform(weights.begin(), weights.end(), std::back_inserter(values), [&val](BoutReal weight) -> PetscScalar { return weight * val; }); - int status; - BOUT_OMP(critical) + int status = 0; + BOUT_OMP_SAFE(critical) status = MatSetValues(*petscMatrix, 1, &petscRow, positions.size(), positions.data(), values.data(), mode); if (status != 0) { @@ -457,46 +415,37 @@ public: }; Element operator()(const ind_type& index1, const ind_type& index2) { - const int global1 = indexConverter->getGlobal(index1), - global2 = indexConverter->getGlobal(index2); + const int global1 = indexConverter->getGlobal(index1); + const int global2 = indexConverter->getGlobal(index2); #if CHECKLEVEL >= 1 if (!initialised) { throw BoutException("Can not return element of uninitialised matrix"); - } else if (global1 == -1 || global2 == -1) { - std::cout << "(" << index1.x() << ", " << index1.y() << ", " << index1.z() << ") "; - std::cout << "(" << index2.x() << ", " << index2.y() << ", " << index2.z() << ")\n"; - throw BoutException("Request to return invalid matrix element"); + } + if (global1 == -1 || global2 == -1) { + throw BoutException( + "Request to return invalid matrix element: (({}, {}, {}), ({}, {}, {}))", + index1.x(), index1.y(), index1.z(), index2.x(), index2.y(), index2.z()); } #endif std::vector positions; std::vector weights; if (yoffset != 0) { ASSERT1(yoffset == index2.y() - index1.y()); - const auto pw = [this, &index1, &index2]() { - if (this->yoffset == -1) { - return pt->getWeightsForYDownApproximation(index2.x(), index1.y(), index2.z()); - } else if (this->yoffset == 1) { - return pt->getWeightsForYUpApproximation(index2.x(), index1.y(), index2.z()); - } else { - return pt->getWeightsForYApproximation(index2.x(), index1.y(), index2.z(), - this->yoffset); - } - }(); - + const auto pws = + pt->getWeightsForYApproximation(index2.x(), index1.y(), index2.z(), yoffset); const int ny = - std::is_same::value ? 1 : indexConverter->getMesh()->LocalNy; - const int nz = - std::is_same::value ? 1 : indexConverter->getMesh()->LocalNz; + std::is_same_v ? 1 : indexConverter->getMesh()->LocalNy; + const int nz = std::is_same_v ? 1 : indexConverter->getMesh()->LocalNz; std::transform( - pw.begin(), pw.end(), std::back_inserter(positions), - [this, ny, nz](ParallelTransform::PositionsAndWeights p) -> PetscInt { + pws.begin(), pws.end(), std::back_inserter(positions), + [this, ny, nz](ParallelTransform::PositionsAndWeights pos) -> PetscInt { return this->indexConverter->getGlobal( - ind_type(p.i * ny * nz + p.j * nz + p.k, ny, nz)); + ind_type(pos.i * ny * nz + pos.j * nz + pos.k, ny, nz)); }); - std::transform(pw.begin(), pw.end(), std::back_inserter(weights), - [](ParallelTransform::PositionsAndWeights p) -> PetscScalar { - return p.weight; + std::transform(pws.begin(), pws.end(), std::back_inserter(weights), + [](ParallelTransform::PositionsAndWeights pos) -> PetscScalar { + return pos.weight; }); } return Element(matrix.get(), global1, global2, positions, weights); @@ -504,20 +453,21 @@ public: BoutReal operator()(const ind_type& index1, const ind_type& index2) const { ASSERT2(yoffset == 0); - const int global1 = indexConverter->getGlobal(index1), - global2 = indexConverter->getGlobal(index2); + const int global1 = indexConverter->getGlobal(index1); + const int global2 = indexConverter->getGlobal(index2); #if CHECKLEVEL >= 1 if (!initialised) { throw BoutException("Can not return element of uninitialised matrix"); - } else if (global1 == -1 || global2 == -1) { - std::cout << "(" << index1.x() << ", " << index1.y() << ", " << index1.z() << ") "; - std::cout << "(" << index2.x() << ", " << index2.y() << ", " << index2.z() << ")\n"; - throw BoutException("Request to return invalid matrix element"); + } + if (global1 == -1 || global2 == -1) { + throw BoutException( + "Request to return invalid matrix element: (({}, {}, {}), ({}, {}, {}))", + index1.x(), index1.y(), index1.z(), index2.x(), index2.y(), index2.z()); } #endif - BoutReal value; - int status; - BOUT_OMP(critical) + BoutReal value = BoutNaN; + int status = 0; + BOUT_OMP_SAFE(critical) status = MatGetValues(*get(), 1, &global1, 1, &global2, &value); if (status != 0) { throw BoutException("Error when getting elements of a PETSc matrix."); @@ -549,7 +499,7 @@ public: PetscMatrix yup(int index = 0) { return ynext(index + 1); } PetscMatrix ydown(int index = 0) { return ynext(-index - 1); } PetscMatrix ynext(int dir) { - if (std::is_same::value && yoffset + dir != 0) { + if (std::is_same_v && yoffset + dir != 0) { throw BoutException("Can not get ynext for FieldPerp"); } PetscMatrix result; // Can't use copy constructor because don't @@ -557,7 +507,7 @@ public: result.matrix = matrix; result.indexConverter = indexConverter; result.pt = pt; - result.yoffset = std::is_same::value ? 0 : yoffset + dir; + result.yoffset = std::is_same_v ? 0 : yoffset + dir; result.initialised = initialised; return result; } @@ -569,8 +519,8 @@ public: private: PetscLib lib; std::shared_ptr matrix = nullptr; - IndexerPtr indexConverter; - ParallelTransform* pt; + IndexerPtr indexConverter{}; + ParallelTransform* pt{}; int yoffset = 0; bool initialised = false; }; @@ -605,7 +555,7 @@ void swap(PetscMatrix& first, PetscMatrix& second) { */ template PetscVector operator*(const PetscMatrix& mat, const PetscVector& vec) { - const Vec rhs = *vec.get(); + Vec rhs = *vec.get(); Vec* result = new Vec(); VecDuplicate(rhs, result); VecAssemblyBegin(*result); @@ -617,4 +567,4 @@ PetscVector operator*(const PetscMatrix& mat, const PetscVector& vec) { #endif // BOUT_HAS_PETSC -#endif // __PETSC_INTERFACE_H__ +#endif // BOUT_PETSC_INTERFACE_H diff --git a/include/bout/petsclib.hxx b/include/bout/petsclib.hxx index dd3daa28aa..2008671286 100644 --- a/include/bout/petsclib.hxx +++ b/include/bout/petsclib.hxx @@ -43,12 +43,10 @@ * **************************************************************************/ -class PetscLib; +#ifndef BOUT_PETSCLIB_H +#define BOUT_PETSCLIB_H -#ifndef __PETSCLIB_H__ -#define __PETSCLIB_H__ - -#include "bout/build_config.hxx" +#include "bout/build_defines.hxx" class Options; @@ -61,12 +59,13 @@ class Options; // means we _must_ `#include` this header _before_ any PETSc header! #define PETSC_HAVE_BROKEN_RECURSIVE_MACRO -#include +#include // IWYU pragma: export #include #include "bout/boutexception.hxx" -#define BOUT_DO_PETSC(cmd) PetscLib::assertIerr(cmd, #cmd) +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define BOUT_DO_PETSC(cmd) PetscLib::assertIerr((cmd), #cmd) /*! * Handles initialisation and finalisation of PETSc library. @@ -81,6 +80,11 @@ public: */ explicit PetscLib(Options* opt = nullptr); + PetscLib(const PetscLib&) = default; + PetscLib(PetscLib&&) = default; + PetscLib& operator=(const PetscLib&) = default; + PetscLib& operator=(PetscLib&&) = default; + /*! * Calls PetscFinalize when all PetscLib instances are destroyed */ @@ -92,9 +96,9 @@ public: * PetscLib are created. * The arguments will be passed to PetscInitialize() */ - static void setArgs(int& c, char**& v) { - pargc = &c; - pargv = &v; + static void setArgs(int& argc, char**& argv) { + pargc = &argc; + pargv = &argv; } /// Set options for a KSP linear solver that uses the options specific to this PetscLib, @@ -115,28 +119,28 @@ public: */ static void cleanup(); - static inline void assertIerr(PetscErrorCode ierr, std::string op = "PETSc operation") { - if (ierr) { - throw BoutException("{:s} failed with {:d}", op, ierr); + static inline void assertIerr(PetscErrorCode ierr, + const std::string& petsc_op = "PETSc operation") { + if (ierr != 0) { + throw BoutException("{:s} failed with {:d}", petsc_op, ierr); } } static BoutException SNESFailure(SNES& snes); private: - static int count; ///< How many instances? - static char help[]; ///< Help string + // NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables) + static inline int count = 0; ///< How many instances? // Command-line arguments - static int* pargc; - static char*** pargv; + static inline int* pargc = nullptr; + static inline char*** pargv = nullptr; // Prefix for object-specific options std::string options_prefix; - static PetscLogEvent USER_EVENT; - - void setPetscOptions(Options& options, const std::string& pass_options_prefix); + static inline PetscLogEvent USER_EVENT; + // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables) }; #ifndef PETSC_VERSION_GE @@ -176,4 +180,4 @@ public: #endif // BOUT_HAS_PETSC -#endif // __PETSCLIB_H__ +#endif // BOUT_PETSCLIB_H diff --git a/include/bout/physicsmodel.hxx b/include/bout/physicsmodel.hxx index a9a7d7344d..9fa25d8b0f 100644 --- a/include/bout/physicsmodel.hxx +++ b/include/bout/physicsmodel.hxx @@ -34,15 +34,15 @@ class PhysicsModel; -#ifndef __PHYSICS_MODEL_H__ -#define __PHYSICS_MODEL_H__ +#ifndef BOUT_PHYSICS_MODEL_H +#define BOUT_PHYSICS_MODEL_H #include "solver.hxx" #include "bout/bout.hxx" #include "bout/macro_for_each.hxx" #include "bout/msg_stack.hxx" #include "bout/options.hxx" -#include "bout/options_netcdf.hxx" +#include "bout/options_io.hxx" #include "bout/sys/variant.hxx" #include "bout/unused.hxx" #include "bout/utils.hxx" @@ -88,9 +88,6 @@ public: void add(Vector2D* value, const std::string& name, bool save_repeat = false); void add(Vector3D* value, const std::string& name, bool save_repeat = false); - /// Write stored data to file immediately - bool write(); - private: /// Helper struct to save enough information so that we can save an /// object to file later @@ -130,11 +127,11 @@ public: using preconfunc = int (PhysicsModel::*)(BoutReal t, BoutReal gamma, BoutReal delta); using jacobianfunc = int (PhysicsModel::*)(BoutReal t); - template ::value>> + template >> using ModelPreconFunc = int (Model::*)(BoutReal t, BoutReal gamma, BoutReal delta); - template ::value>> + template >> using ModelJacobianFunc = int (Model::*)(BoutReal t); PhysicsModel(); @@ -148,7 +145,7 @@ public: bout::DataFileFacade restart{}; /*! - * Initialse the model, calling the init() and postInit() methods + * Initialise the model, calling the init() and postInit() methods * * Note: this is usually only called by the Solver */ @@ -383,13 +380,13 @@ private: /// State for outputs Options output_options; /// File to write the outputs to - bout::OptionsNetCDF output_file; + std::unique_ptr output_file; /// Should we write output files bool output_enabled{true}; /// Stores the state for restarting Options restart_options; /// File to write the restart-state to - bout::OptionsNetCDF restart_file; + std::unique_ptr restart_file; /// Should we write restart files bool restart_enabled{true}; /// Split operator model? @@ -569,4 +566,4 @@ private: #define SAVE_REPEAT(...) \ { MACRO_FOR_EACH(SAVE_REPEAT1, __VA_ARGS__) } -#endif // __PHYSICS_MODEL_H__ +#endif // BOUT_PHYSICS_MODEL_H diff --git a/include/bout/region.hxx b/include/bout/region.hxx index e4313f8256..4649b680eb 100644 --- a/include/bout/region.hxx +++ b/include/bout/region.hxx @@ -39,18 +39,25 @@ /// because an Ind2D essentially doesn't keep track of the /// z-dimension. -#ifndef __REGION_H__ -#define __REGION_H__ +#ifndef BOUT_REGION_H +#define BOUT_REGION_H #include #include +#include #include #include #include #include "bout/assert.hxx" #include "bout/bout_types.hxx" -#include "bout/openmpwrap.hxx" +#include "bout/boutexception.hxx" +#include "bout/build_defines.hxx" +#include "bout/openmpwrap.hxx" // IWYU pragma: keep + +class BoutMask; + +// NOLINTBEGIN(cppcoreguidelines-macro-usage,bugprone-macro-parentheses) /// The MAXREGIONBLOCKSIZE value can be tuned to try to optimise /// performance on specific hardware. It determines what the largest @@ -109,16 +116,16 @@ /// } // -#define BOUT_FOR_SERIAL(index, region) \ - for (auto block = region.getBlocks().cbegin(), end = region.getBlocks().cend(); \ - block < end; ++block) \ +#define BOUT_FOR_SERIAL(index, region) \ + for (auto block = (region).getBlocks().cbegin(), end = (region).getBlocks().cend(); \ + block < end; ++block) \ for (auto index = block->first; index < block->second; ++index) #if BOUT_USE_OPENMP -#define BOUT_FOR_OMP(index, region, omp_pragmas) \ - BOUT_OMP(omp_pragmas) \ - for (auto block = region.getBlocks().cbegin(); block < region.getBlocks().cend(); \ - ++block) \ +#define BOUT_FOR_OMP(index, region, omp_pragmas) \ + BOUT_OMP_PERF(omp_pragmas) \ + for (auto block = (region).getBlocks().cbegin(); block < (region).getBlocks().cend(); \ + ++block) \ for (auto index = block->first; index < block->second; ++index) #else // No OpenMP, so fall back to slightly more efficient serial form @@ -126,10 +133,11 @@ #endif #define BOUT_FOR(index, region) \ - BOUT_FOR_OMP(index, region, parallel for schedule(BOUT_OPENMP_SCHEDULE)) + BOUT_FOR_OMP(index, (region), parallel for schedule(BOUT_OPENMP_SCHEDULE)) #define BOUT_FOR_INNER(index, region) \ - BOUT_FOR_OMP(index, region, for schedule(BOUT_OPENMP_SCHEDULE) nowait) + BOUT_FOR_OMP(index, (region), for schedule(BOUT_OPENMP_SCHEDULE) nowait) +// NOLINTEND(cppcoreguidelines-macro-usage,bugprone-macro-parentheses) enum class IND_TYPE { IND_3D = 0, IND_2D = 1, IND_PERP = 2 }; @@ -231,7 +239,7 @@ struct SpecificInd { /// and is determined by the `dir` template argument. The offset corresponds /// to the `dd` template argument. template - const inline SpecificInd plus() const { + inline SpecificInd plus() const { static_assert(dir == DIRECTION::X || dir == DIRECTION::Y || dir == DIRECTION::Z || dir == DIRECTION::YAligned || dir == DIRECTION::YOrthogonal, "Unhandled DIRECTION in SpecificInd::plus"); @@ -251,7 +259,7 @@ struct SpecificInd { /// and is determined by the `dir` template argument. The offset corresponds /// to the `dd` template argument. template - const inline SpecificInd minus() const { + inline SpecificInd minus() const { static_assert(dir == DIRECTION::X || dir == DIRECTION::Y || dir == DIRECTION::Z || dir == DIRECTION::YAligned || dir == DIRECTION::YOrthogonal, "Unhandled DIRECTION in SpecificInd::minus"); @@ -267,11 +275,11 @@ struct SpecificInd { } } - const inline SpecificInd xp(int dx = 1) const { return {ind + (dx * ny * nz), ny, nz}; } + inline SpecificInd xp(int dx = 1) const { return {ind + (dx * ny * nz), ny, nz}; } /// The index one point -1 in x - const inline SpecificInd xm(int dx = 1) const { return xp(-dx); } + inline SpecificInd xm(int dx = 1) const { return xp(-dx); } /// The index one point +1 in y - const inline SpecificInd yp(int dy = 1) const { + inline SpecificInd yp(int dy = 1) const { #if CHECK >= 4 if (y() + dy < 0 or y() + dy >= ny) { throw BoutException("Offset in y ({:d}) would go out of bounds at {:d}", dy, ind); @@ -281,12 +289,12 @@ struct SpecificInd { return {ind + (dy * nz), ny, nz}; } /// The index one point -1 in y - const inline SpecificInd ym(int dy = 1) const { return yp(-dy); } + inline SpecificInd ym(int dy = 1) const { return yp(-dy); } /// The index one point +1 in z. Wraps around zend to zstart /// An alternative, non-branching calculation is : /// ind + dz - nz * ((ind + dz) / nz - ind / nz) /// but this appears no faster (and perhaps slower). - const inline SpecificInd zp(int dz = 1) const { + inline SpecificInd zp(int dz = 1) const { ASSERT3(dz >= 0); dz = dz <= nz ? dz : dz % nz; //Fix in case dz > nz, if not force it to be in range return {(ind + dz) % nz < dz ? ind - nz + dz : ind + dz, ny, nz}; @@ -295,22 +303,22 @@ struct SpecificInd { /// An alternative, non-branching calculation is : /// ind - dz + nz * ( (nz + ind) / nz - (nz + ind - dz) / nz) /// but this appears no faster (and perhaps slower). - const inline SpecificInd zm(int dz = 1) const { + inline SpecificInd zm(int dz = 1) const { dz = dz <= nz ? dz : dz % nz; //Fix in case dz > nz, if not force it to be in range ASSERT3(dz >= 0); return {(ind) % nz < dz ? ind + nz - dz : ind - dz, ny, nz}; } // and for 2 cells - const inline SpecificInd xpp() const { return xp(2); } - const inline SpecificInd xmm() const { return xm(2); } - const inline SpecificInd ypp() const { return yp(2); } - const inline SpecificInd ymm() const { return ym(2); } - const inline SpecificInd zpp() const { return zp(2); } - const inline SpecificInd zmm() const { return zm(2); } + inline SpecificInd xpp() const { return xp(2); } + inline SpecificInd xmm() const { return xm(2); } + inline SpecificInd ypp() const { return yp(2); } + inline SpecificInd ymm() const { return ym(2); } + inline SpecificInd zpp() const { return zp(2); } + inline SpecificInd zmm() const { return zm(2); } /// Generic offset of \p index in multiple directions simultaneously - const inline SpecificInd offset(int dx, int dy, int dz) const { + inline SpecificInd offset(int dx, int dy, int dz) const { auto temp = (dz > 0) ? zp(dz) : zm(-dz); return temp.yp(dy).xp(dx); } @@ -379,16 +387,16 @@ using Ind2D = SpecificInd; using IndPerp = SpecificInd; /// Get string representation of Ind3D -inline const std::string toString(const Ind3D& i) { +inline std::string toString(const Ind3D& i) { return "(" + std::to_string(i.x()) + ", " + std::to_string(i.y()) + ", " + std::to_string(i.z()) + ")"; } /// Get string representation of Ind2D -inline const std::string toString(const Ind2D& i) { +inline std::string toString(const Ind2D& i) { return "(" + std::to_string(i.x()) + ", " + std::to_string(i.y()) + ")"; } /// Get string representation of IndPerp -inline const std::string toString(const IndPerp& i) { +inline std::string toString(const IndPerp& i) { return "(" + std::to_string(i.x()) + ", " + std::to_string(i.z()) + ")"; } @@ -481,9 +489,10 @@ template class Region { // Following prevents a Region being created with anything other // than Ind2D, Ind3D or IndPerp as template type - static_assert(std::is_base_of::value || std::is_base_of::value - || std::is_base_of::value, - "Region must be templated with one of IndPerp, Ind2D or Ind3D"); + static_assert( + std::is_base_of_v< + Ind2D, T> || std::is_base_of_v || std::is_base_of_v, + "Region must be templated with one of IndPerp, Ind2D or Ind3D"); public: using data_type = T; @@ -514,13 +523,13 @@ public: // Want to make this private to disable but think it may be needed as we put Regions // into maps which seems to need to be able to make "empty" objects. - Region() = default; + Region() = default; - Region(int xstart, int xend, int ystart, int yend, int zstart, int zend, int ny, - int nz, int maxregionblocksize = MAXREGIONBLOCKSIZE) + Region(int xstart, int xend, int ystart, int yend, int zstart, int zend, int ny, int nz, + int maxregionblocksize = MAXREGIONBLOCKSIZE) : ny(ny), nz(nz) { #if CHECK > 1 - if (std::is_base_of::value) { + if constexpr (std::is_base_of_v) { if (nz != 1) { throw BoutException( "Trying to make Region with nz = {:d}, but expected nz = 1", nz); @@ -536,7 +545,7 @@ public: } } - if (std::is_base_of::value) { + if constexpr (std::is_base_of_v) { if (ny != 1) { throw BoutException( "Trying to make Region with ny = {:d}, but expected ny = 1", ny); @@ -558,15 +567,17 @@ public: blocks = getContiguousBlocks(maxregionblocksize); }; - Region(RegionIndices& indices, int maxregionblocksize = MAXREGIONBLOCKSIZE) - : indices(indices) { - blocks = getContiguousBlocks(maxregionblocksize); - }; + Region(RegionIndices& indices, int maxregionblocksize = MAXREGIONBLOCKSIZE) + : indices(indices), blocks(getContiguousBlocks(maxregionblocksize)){}; - Region(ContiguousBlocks& blocks) : blocks(blocks) { indices = getRegionIndices(); }; + // We need to first set the blocks, and only after that call getRegionIndices. + // Do not put in the member initialisation + // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer) + Region(ContiguousBlocks& blocks) : blocks(blocks) { indices = getRegionIndices(); }; - /// Destructor - ~Region() = default; + bool operator==(const Region& other) const { + return std::equal(this->begin(), this->end(), other.begin(), other.end()); + } /// Expose the iterator over indices for use in range-based /// for-loops or with STL algorithms, etc. @@ -644,7 +655,6 @@ public: auto currentIndices = getIndices(); // Lambda that returns true/false depending if the passed value is in maskIndices - // With C++14 T can be auto instead auto isInVector = [&](T val) { return std::binary_search(std::begin(maskIndices), std::end(maskIndices), val); }; @@ -660,8 +670,28 @@ public: return *this; // To allow command chaining }; - /// Returns a new region including only indices contained in both - /// this region and the other. + /// Return a new region equivalent to *this but with indices contained + /// in mask Region removed + Region mask(const BoutMask& mask) { + // Get the current set of indices that we're going to mask and then + // use to create the result region. + auto currentIndices = getIndices(); + + // Lambda that returns true/false depending if the passed value is in maskIndices + auto isInVector = [&](T val) { return mask[val]; }; + + // Erase elements of currentIndices that are in maskIndices + currentIndices.erase( + std::remove_if(std::begin(currentIndices), std::end(currentIndices), isInVector), + std::end(currentIndices)); + + // Update indices + setIndices(currentIndices); + + return *this; // To allow command chaining + }; + + /// Get a new region including only indices that are in both regions. Region getIntersection(const Region& otherRegion) { // Get other indices and sort as we're going to be searching through // this vector so if it's sorted we can be more efficient @@ -673,7 +703,6 @@ public: auto currentIndices = getIndices(); // Lambda that returns true/false depending if the passed value is in otherIndices - // With C++14 T can be auto instead auto notInVector = [&](T val) { return !std::binary_search(std::begin(otherIndices), std::end(otherIndices), val); }; @@ -736,8 +765,8 @@ public: // globalPos = (index/period) * period; // Find which period block we're in // newIndex = globalPos + localPos; for (unsigned int i = 0; i < newInd.size(); i++) { - int index = newInd[i].ind; - int whichBlock = index / period; + const int index = newInd[i].ind; + const int whichBlock = index / period; newInd[i].ind = ((index + shift) % period) + period * whichBlock; }; @@ -761,20 +790,21 @@ public: std::vector blockSizes(result.numBlocks); // Get the size of each block using lambda to calculate size - std::transform(std::begin(blocks), std::end(blocks), std::begin(blockSizes), - [](const ContiguousBlock& a) { return a.second.ind - a.first.ind; }); + std::transform( + std::begin(blocks), std::end(blocks), std::begin(blockSizes), + [](const ContiguousBlock& block) { return block.second.ind - block.first.ind; }); auto minMaxSize = std::minmax_element(std::begin(blockSizes), std::end(blockSizes)); - result.minBlockSize = - *(minMaxSize.first); //Note have to derefence to get actual value - result.numMinBlocks = - std::count(std::begin(blockSizes), std::end(blockSizes), result.minBlockSize); + // Note have to derefence to get actual value + result.minBlockSize = *(minMaxSize.first); + result.numMinBlocks = static_cast( + std::count(std::begin(blockSizes), std::end(blockSizes), result.minBlockSize)); - result.maxBlockSize = - *(minMaxSize.second); //Note have to derefence to get actual value - result.numMaxBlocks = - std::count(std::begin(blockSizes), std::end(blockSizes), result.maxBlockSize); + // Note have to derefence to get actual value + result.maxBlockSize = *(minMaxSize.second); + result.numMaxBlocks = static_cast( + std::count(std::begin(blockSizes), std::end(blockSizes), result.maxBlockSize)); result.maxImbalance = static_cast(result.maxBlockSize) / static_cast(result.minBlockSize); @@ -829,10 +859,10 @@ private: int z = zstart; bool done = false; - int j = -1; + int ind = -1; while (!done) { - j++; - region[j].ind = (x * ny + y) * nz + z; + ind++; + region[ind].ind = (x * ny + y) * nz + z; if (x == xend && y == yend && z == zend) { done = true; } @@ -918,7 +948,7 @@ Region mask(const Region& region, const Region& mask) { /// Return the intersection of two regions template -Region getIntersection(const Region& region, const Region& otherRegion) { +Region intersection(const Region& region, const Region& otherRegion) { auto result = region; return result.getIntersection(otherRegion); } @@ -955,4 +985,4 @@ unsigned int size(const Region& region) { return region.size(); } -#endif /* __REGION_H__ */ +#endif /* BOUT_REGION_H */ diff --git a/include/bout/revision.hxx.in b/include/bout/revision.hxx.in index f0e3abdb8b..393e8cc34f 100644 --- a/include/bout/revision.hxx.in +++ b/include/bout/revision.hxx.in @@ -7,18 +7,16 @@ #ifndef BOUT_REVISION_H #define BOUT_REVISION_H -// TODO: Make these all `inline` when we upgrade to C++17 - namespace bout { namespace version { /// The git commit hash #ifndef BOUT_REVISION -constexpr auto revision = "@BOUT_REVISION@"; +inline constexpr auto revision = "@BOUT_REVISION@"; #else // Stringify value passed at compile time #define BUILDFLAG1_(x) #x #define BUILDFLAG(x) BUILDFLAG1_(x) -constexpr auto revision = BUILDFLAG(BOUT_REVISION); +inline constexpr auto revision = BUILDFLAG(BOUT_REVISION); #undef BUILDFLAG1 #undef BUILDFLAG #endif diff --git a/include/bout/rkscheme.hxx b/include/bout/rkscheme.hxx index f4e5959aff..ba818c04fe 100644 --- a/include/bout/rkscheme.hxx +++ b/include/bout/rkscheme.hxx @@ -32,8 +32,8 @@ class RKScheme; -#ifndef __RKSCHEME_H__ -#define __RKSCHEME_H__ +#ifndef BOUT_RKSCHEME_H +#define BOUT_RKSCHEME_H #include "bout/generic_factory.hxx" #include @@ -140,4 +140,4 @@ private: void zeroSteps(); }; -#endif // __RKSCHEME_H__ +#endif // BOUT_RKSCHEME_H diff --git a/include/bout/rvec.hxx b/include/bout/rvec.hxx index 0b611d64bf..492228b9ea 100644 --- a/include/bout/rvec.hxx +++ b/include/bout/rvec.hxx @@ -1,11 +1,11 @@ #pragma once -#ifndef __RVEC_H__ -#define __RVEC_H__ +#ifndef BOUT_RVEC_H +#define BOUT_RVEC_H #include #include using rvec = std::vector; -#endif // __RVEC_H__ +#endif // BOUT_RVEC_H diff --git a/include/bout/scorepwrapper.hxx b/include/bout/scorepwrapper.hxx index 210d48e49f..2eb67cda30 100644 --- a/include/bout/scorepwrapper.hxx +++ b/include/bout/scorepwrapper.hxx @@ -1,5 +1,5 @@ -#ifndef __BOUT_SCOREP_H__ -#define __BOUT_SCOREP_H__ +#ifndef BOUT_SCOREP_H +#define BOUT_SCOREP_H #include "bout/build_config.hxx" diff --git a/include/bout/single_index_ops.hxx b/include/bout/single_index_ops.hxx index 6a9089510b..60bd78bc36 100644 --- a/include/bout/single_index_ops.hxx +++ b/include/bout/single_index_ops.hxx @@ -16,7 +16,7 @@ using EXEC_POL = RAJA::cuda_exec; using EXEC_POL = RAJA::loop_exec; #endif // end BOUT_USE_CUDA ////-----------CUDA settings------------------------------------------------------end -#endif +#endif // end BOUT_HAS_RAJA // Ind3D: i.zp(): BOUT_HOST_DEVICE inline int i_zp(const int id, const int nz) { diff --git a/include/bout/slepclib.hxx b/include/bout/slepclib.hxx index f6df9ce98c..e59a9c2913 100644 --- a/include/bout/slepclib.hxx +++ b/include/bout/slepclib.hxx @@ -42,8 +42,8 @@ class SlepcLib; -#ifndef __SLEPCLIB_H__ -#define __SLEPCLIB_H__ +#ifndef BOUT_SLEPCLIB_H +#define BOUT_SLEPCLIB_H #include "bout/build_config.hxx" @@ -89,4 +89,4 @@ public: #endif // BOUT_HAS_SLEPC -#endif // __SLEPCLIB_H__ +#endif // BOUT_SLEPCLIB_H diff --git a/include/bout/smoothing.hxx b/include/bout/smoothing.hxx index 8a0d6e81b8..9485602053 100644 --- a/include/bout/smoothing.hxx +++ b/include/bout/smoothing.hxx @@ -25,8 +25,8 @@ * **************************************************************/ -#ifndef __SMOOTHING_H__ -#define __SMOOTHING_H__ +#ifndef BOUT_SMOOTHING_H +#define BOUT_SMOOTHING_H #include "bout/field3d.hxx" @@ -135,4 +135,4 @@ const Field3D nl_filter_z(const Field3D& f, BoutReal w = 1.0); */ const Field3D nl_filter(const Field3D& f, BoutReal w = 1.0); -#endif // __SMOOTHING_H__ +#endif // BOUT_SMOOTHING_H diff --git a/include/bout/solver.hxx b/include/bout/solver.hxx index 8a3f07c27a..47fef7ce73 100644 --- a/include/bout/solver.hxx +++ b/include/bout/solver.hxx @@ -33,8 +33,8 @@ * **************************************************************************/ -#ifndef __SOLVER_H__ -#define __SOLVER_H__ +#ifndef SOLVER_H +#define SOLVER_H #include "bout/build_config.hxx" @@ -63,7 +63,6 @@ using Jacobian = int (*)(BoutReal t); /// Solution monitor, called each timestep using TimestepMonitorFunc = int (*)(Solver* solver, BoutReal simtime, BoutReal lastdt); -//#include "bout/globals.hxx" #include "bout/field2d.hxx" #include "bout/field3d.hxx" #include "bout/generic_factory.hxx" @@ -270,7 +269,7 @@ public: virtual void constraint(Vector3D& v, Vector3D& C_v, std::string name); /// Set a maximum internal timestep (only for explicit schemes) - virtual void setMaxTimestep(MAYBE_UNUSED(BoutReal dt)) {} + virtual void setMaxTimestep([[maybe_unused]] BoutReal dt) {} /// Return the current internal timestep virtual BoutReal getCurrentTimestep() { return 0.0; } @@ -400,16 +399,6 @@ protected: return in_vars != end(vars); } - /// Helper function for getLocalN: return the number of points to - /// evolve in \p f, plus the accumulator \p value - /// - /// If f.evolve_bndry, includes the boundary (NB: not guard!) points - /// - /// FIXME: This could be a lambda local to getLocalN with an `auto` - /// argument in C++14 - template - friend int local_N_sum(int value, const VarStr& f); - /// Vectors of variables to evolve std::vector> f2d; std::vector> f3d; @@ -440,6 +429,8 @@ protected: bool has_constraints{false}; /// Has init been called yet? bool initialised{false}; + /// If calling user RHS for the first time + bool first_rhs_call{true}; /// Current simulation time BoutReal simtime{0.0}; @@ -597,4 +588,4 @@ private: BoutReal output_timestep; }; -#endif // __SOLVER_H__ +#endif // SOLVER_H diff --git a/include/bout/solverfactory.hxx b/include/bout/solverfactory.hxx index a628aed0c1..a0ecd646b8 100644 --- a/include/bout/solverfactory.hxx +++ b/include/bout/solverfactory.hxx @@ -1,5 +1,5 @@ -#ifndef __SOLVER_FACTORY_H__ -#define __SOLVER_FACTORY_H__ +#ifndef BOUT_SOLVER_FACTORY_H +#define BOUT_SOLVER_FACTORY_H #ifndef _MSC_VER #warning("Deprecated header: use #include instead") @@ -9,4 +9,4 @@ #include -#endif // __SOLVER_FACTORY_H__ +#endif // BOUT_SOLVER_FACTORY_H diff --git a/include/bout/sourcex.hxx b/include/bout/sourcex.hxx index 6727c8bcc9..e01c469af6 100644 --- a/include/bout/sourcex.hxx +++ b/include/bout/sourcex.hxx @@ -2,8 +2,8 @@ * Radial mask operators **************************************************************/ -#ifndef __MASKX_H__ -#define __MASKX_H__ +#ifndef BOUT_MASKX_H +#define BOUT_MASKX_H #include "bout/field3d.hxx" @@ -21,4 +21,4 @@ const Field3D sink_tanhxr(const Field2D& f0, const Field3D& f, BoutReal swidth, const Field3D buff_x(const Field3D& f, bool BoutRealspace = true); -#endif // __MASKX_H__ +#endif // BOUT_MASKX_H diff --git a/include/bout/stencils.hxx b/include/bout/stencils.hxx index fa55e7dd2d..2466047297 100644 --- a/include/bout/stencils.hxx +++ b/include/bout/stencils.hxx @@ -25,8 +25,8 @@ * **************************************************************************/ -#ifndef __STENCILS_H__ -#define __STENCILS_H__ +#ifndef BOUT_STENCILS_H +#define BOUT_STENCILS_H #include "bout/bout_types.hxx" @@ -125,4 +125,4 @@ stencil inline populateStencil(const FieldType& f, const typename FieldType::ind populateStencil(s, f, i); return s; } -#endif /* __STENCILS_H__ */ +#endif /* BOUT_STENCILS_H */ diff --git a/include/bout/sundials_backports.hxx b/include/bout/sundials_backports.hxx index c5e0f3ab15..4ec334f4d4 100644 --- a/include/bout/sundials_backports.hxx +++ b/include/bout/sundials_backports.hxx @@ -1,81 +1,74 @@ -// Backports for SUNDIALS compatibility between versions 3-6 +// Backports for SUNDIALS compatibility between versions 4-7 // // These are common backports shared between the CVode, ARKode, and IDA solvers // // Copyright 2022 Peter Hill, BOUT++ Team -// SPDX-License-Identifier: LGPLv3 +// SPDX-License-Identifier: LGPL-3.0-or-later #ifndef BOUT_SUNDIALS_BACKPORTS_H #define BOUT_SUNDIALS_BACKPORTS_H +#include "bout/bout_types.hxx" + +#include + #include #include #include +#include #include - -#if SUNDIALS_VERSION_MAJOR >= 3 #include -#endif - -#if SUNDIALS_VERSION_MAJOR >= 4 -#include #include #include -#endif - -#include "bout/unused.hxx" -#if SUNDIALS_VERSION_MAJOR < 3 -using SUNLinearSolver = int*; -inline void SUNLinSolFree(MAYBE_UNUSED(SUNLinearSolver solver)) {} -using sunindextype = long int; +#if SUNDIALS_VERSION_MAJOR >= 6 +#include #endif -#if SUNDIALS_VERSION_MAJOR < 4 -using SUNNonlinearSolver = int*; -inline void SUNNonlinSolFree(MAYBE_UNUSED(SUNNonlinearSolver solver)) {} +#if SUNDIALS_VERSION_MAJOR < 6 +using sundials_real_type = realtype; +#else +using sundials_real_type = sunrealtype; #endif -#if SUNDIALS_VERSION_MAJOR < 6 -namespace sundials { -struct Context { - Context(void* comm MAYBE_UNUSED()) {} -}; -} // namespace sundials +static_assert(std::is_same_v, + "BOUT++ and SUNDIALS real types do not match"); -using SUNContext = sundials::Context; +#define SUNDIALS_CONTROLLER_SUPPORT \ + (SUNDIALS_VERSION_MAJOR > 6 \ + || SUNDIALS_VERSION_MAJOR == 6 && SUNDIALS_VERSION_MINOR >= 7) +#define SUNDIALS_TABLE_BY_NAME_SUPPORT \ + (SUNDIALS_VERSION_MAJOR > 6 \ + || SUNDIALS_VERSION_MAJOR == 6 && SUNDIALS_VERSION_MINOR >= 4) +#if SUNDIALS_VERSION_MAJOR < 6 constexpr auto SUN_PREC_RIGHT = PREC_RIGHT; constexpr auto SUN_PREC_LEFT = PREC_LEFT; constexpr auto SUN_PREC_NONE = PREC_NONE; -inline N_Vector N_VNew_Parallel(MPI_Comm comm, sunindextype local_length, - sunindextype global_length, - MAYBE_UNUSED(SUNContext sunctx)) { - return N_VNew_Parallel(comm, local_length, global_length); -} +namespace sundials { +using Context = std::nullptr_t; +} // namespace sundials +#endif -#if SUNDIALS_VERSION_MAJOR >= 3 -inline SUNLinearSolver SUNLinSol_SPGMR(N_Vector y, int pretype, int maxl, - MAYBE_UNUSED(SUNContext sunctx)) { -#if SUNDIALS_VERSION_MAJOR == 3 - return SUNSPGMR(y, pretype, maxl); +inline sundials::Context createSUNContext([[maybe_unused]] MPI_Comm& comm) { +#if SUNDIALS_VERSION_MAJOR < 6 + return nullptr; +#elif SUNDIALS_VERSION_MAJOR < 7 + return sundials::Context(static_cast(&comm)); #else - return SUNLinSol_SPGMR(y, pretype, maxl); + return sundials::Context(comm); #endif } -#if SUNDIALS_VERSION_MAJOR >= 4 -inline SUNNonlinearSolver SUNNonlinSol_FixedPoint(N_Vector y, int m, - MAYBE_UNUSED(SUNContext sunctx)) { - return SUNNonlinSol_FixedPoint(y, m); -} -inline SUNNonlinearSolver SUNNonlinSol_Newton(N_Vector y, - MAYBE_UNUSED(SUNContext sunctx)) { - return SUNNonlinSol_Newton(y); +template +inline decltype(auto) callWithSUNContext(Func f, [[maybe_unused]] sundials::Context& ctx, + Args&&... args) { +#if SUNDIALS_VERSION_MAJOR < 6 + return f(std::forward(args)...); +#else + return f(std::forward(args)..., ctx); +#endif } -#endif // SUNDIALS_VERSION_MAJOR >= 4 -#endif // SUNDIALS_VERSION_MAJOR >= 3 -#endif // SUNDIALS_VERSION_MAJOR < 6 #endif // BOUT_SUNDIALS_BACKPORTS_H diff --git a/include/bout/surfaceiter.hxx b/include/bout/surfaceiter.hxx index ebe33b9864..a031b30ba6 100644 --- a/include/bout/surfaceiter.hxx +++ b/include/bout/surfaceiter.hxx @@ -4,8 +4,8 @@ class SurfaceIter; -#ifndef __SURFACEITER_H__ -#define __SURFACEITER_H__ +#ifndef BOUT_SURFACEITER_H +#define BOUT_SURFACEITER_H #include "mesh.hxx" @@ -63,4 +63,4 @@ private: const int lastpos; }; -#endif // __SURFACEITER_H__ +#endif // BOUT_SURFACEITER_H diff --git a/include/bout/sys/expressionparser.hxx b/include/bout/sys/expressionparser.hxx index 0ee3a7f97b..660ad20ab3 100644 --- a/include/bout/sys/expressionparser.hxx +++ b/include/bout/sys/expressionparser.hxx @@ -3,9 +3,9 @@ * * Parses strings containing expressions, returning a tree of generators * - * Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu + * Copyright 2010-2024 BOUT++ contributors * - * Contact: Ben Dudson, bd512@york.ac.uk + * Contact: Ben Dudson, dudson2@llnl.gov * * This file is part of BOUT++. * @@ -24,10 +24,9 @@ * **************************************************************************/ -#ifndef __EXPRESSION_PARSER_H__ -#define __EXPRESSION_PARSER_H__ +#ifndef EXPRESSION_PARSER_H +#define EXPRESSION_PARSER_H -#include "bout/format.hxx" #include "bout/unused.hxx" #include "fmt/core.h" @@ -158,7 +157,7 @@ protected: /// Characters which cannot be used in symbols without escaping; /// all other allowed. In addition, whitespace cannot be used. /// Adding a binary operator adds its symbol to this string - std::string reserved_chars = "+-*/^[](){},="; + std::string reserved_chars = "+-*/^[](){},=!"; private: std::map gen; ///< Generators, addressed by name @@ -260,4 +259,4 @@ private: std::string message; }; -#endif // __EXPRESSION_PARSER_H__ +#endif // EXPRESSION_PARSER_H diff --git a/include/bout/sys/generator_context.hxx b/include/bout/sys/generator_context.hxx index 3f912ec1da..bbe60fab65 100644 --- a/include/bout/sys/generator_context.hxx +++ b/include/bout/sys/generator_context.hxx @@ -27,11 +27,11 @@ public: /// Context(int ix, int iy, int iz, CELL_LOC loc, Mesh* msh, BoutReal t); + /// Specify the values directly + Context(BoutReal x, BoutReal y, BoutReal z, Mesh* msh, BoutReal t); + /// If constructed without parameters, contains no values (null). - /// Requesting x,y,z or t should throw an exception - /// - /// NOTE: For backward compatibility, all locations are set to zero. - /// This should be changed in a future release. + /// Requesting x,y,z or t throws an exception Context() = default; /// The location on the boundary @@ -60,7 +60,13 @@ public: } /// Retrieve a value previously set - BoutReal get(const std::string& name) const { return parameters.at(name); } + BoutReal get(const std::string& name) const { + auto it = parameters.find(name); + if (it != parameters.end()) { + return it->second; + } + throw BoutException("Generator context doesn't contain '{:s}'", name); + } /// Get the mesh for this context (position) /// If the mesh is null this will throw a BoutException (if CHECK >= 1) @@ -73,8 +79,7 @@ private: Mesh* localmesh{nullptr}; ///< The mesh on which the position is defined /// Contains user-set values which can be set and retrieved - std::map parameters{ - {"x", 0.0}, {"y", 0.0}, {"z", 0.0}, {"t", 0.0}}; + std::map parameters{}; }; } // namespace generator diff --git a/include/bout/sys/gettext.hxx b/include/bout/sys/gettext.hxx index 2ada87ab63..a17412118c 100644 --- a/include/bout/sys/gettext.hxx +++ b/include/bout/sys/gettext.hxx @@ -1,7 +1,7 @@ /// Support for i18n using GNU gettext -#ifndef __BOUT_GETTEXT_H__ -#define __BOUT_GETTEXT_H__ +#ifndef BOUT_GETTEXT_H +#define BOUT_GETTEXT_H #include "bout/build_config.hxx" @@ -19,4 +19,4 @@ #define _(string) string #endif // BOUT_HAS_GETTEXT -#endif // __BOUT_GETTEXT_H__ +#endif // BOUT_GETTEXT_H diff --git a/include/bout/sys/range.hxx b/include/bout/sys/range.hxx index a210983f25..9d8aa96cd7 100644 --- a/include/bout/sys/range.hxx +++ b/include/bout/sys/range.hxx @@ -21,8 +21,8 @@ */ -#ifndef __RANGE_H__ -#define __RANGE_H__ +#ifndef BOUT_RANGE_H +#define BOUT_RANGE_H class RangeIterator { public: @@ -74,4 +74,4 @@ private: bool delete_next = false; // Flag to delete this->n if we created it }; -#endif // __RANGE_H__ +#endif // BOUT_RANGE_H diff --git a/include/bout/sys/timer.hxx b/include/bout/sys/timer.hxx index 6f04630c9d..f3beba27b1 100644 --- a/include/bout/sys/timer.hxx +++ b/include/bout/sys/timer.hxx @@ -1,5 +1,5 @@ -#ifndef __TIMER_H__ -#define __TIMER_H__ +#ifndef BOUT_TIMER_H +#define BOUT_TIMER_H #include #include @@ -134,4 +134,4 @@ public: }; #define AUTO_TIME() Timer CONCATENATE(time_, __LINE__)(__thefunc__) -#endif // __TIMER_H__ +#endif // BOUT_TIMER_H diff --git a/include/bout/sys/uncopyable.hxx b/include/bout/sys/uncopyable.hxx index 76606620ed..35418cb7f6 100644 --- a/include/bout/sys/uncopyable.hxx +++ b/include/bout/sys/uncopyable.hxx @@ -1,7 +1,7 @@ // From Scott Meyers' "Effective C++, third edition" -#ifndef __UNCOPYABLE_H__ -#define __UNCOPYABLE_H__ +#ifndef BOUT_UNCOPYABLE_H +#define BOUT_UNCOPYABLE_H /// Inherit from this class (private) to prevent copying class Uncopyable { @@ -14,4 +14,4 @@ public: Uncopyable& operator=(const Uncopyable&) = delete; }; -#endif // __UNCOPYABLE_H__ +#endif // BOUT_UNCOPYABLE_H diff --git a/include/bout/template_combinations.hxx b/include/bout/template_combinations.hxx index 81848cf252..49a42e6bca 100644 --- a/include/bout/template_combinations.hxx +++ b/include/bout/template_combinations.hxx @@ -27,8 +27,8 @@ * **************************************************************************/ -#ifndef __TEMPLATE_COMBINATIONS_H__ -#define __TEMPLATE_COMBINATIONS_H__ +#ifndef BOUT_TEMPLATE_COMBINATIONS_H +#define BOUT_TEMPLATE_COMBINATIONS_H #include diff --git a/include/bout/traits.hxx b/include/bout/traits.hxx index ecfdec8a40..4e03d6b526 100644 --- a/include/bout/traits.hxx +++ b/include/bout/traits.hxx @@ -12,66 +12,51 @@ class Options; namespace bout { namespace utils { -namespace details { -/// Helper class for fold expressions pre-C++17 -/// -/// Taken from "C++ Templates: The Complete Guide, Second Edition" -/// Addison-Wesley, 2017 -/// ISBN-13: 978-0-321-71412-1 -/// ISBN-10: 0-321-71412-1 -/// Copyright © 2017 by Addison-Wesley, David Vandevoorde, Nicolai -/// M. Josuttis, and Douglas Gregor. -constexpr bool and_all() { return true; } template -constexpr bool and_all(T cond) { - return cond; -} -template -constexpr bool and_all(T cond, Ts... conds) { - return cond and and_all(conds...); -} -} // namespace details - -/// If `T` is derived from `Field`, provides the member constant -/// `value` equal to `true`. Otherwise `value is `false`. -/// -/// The following is C++14, but simplifies the use of `is_field`: -/// -/// template -/// constexpr bool is_field_v = is_field::value; +using is_Field = std::is_base_of; + +/// True if `T` is derived from `Field`, otherwise false /// /// Examples /// -------- /// /// template /// void print_field(const T& field) { -/// static_assert(bout::utils::is_field::value, +/// static_assert(bout::utils::is_Field_v, /// "print_field only works with Field2Ds, Field3Ds or FieldPerps") /// // implementation /// } template -using is_Field = std::is_base_of; +inline constexpr bool is_Field_v = std::is_base_of_v; -/// If `T` is derived from `Field2D`, provides the member constant -/// `value` equal to `true`. Otherwise `value is `false`. template using is_Field2D = std::is_base_of; -/// If `T` is derived from `Field3D`, provides the member constant -/// `value` equal to `true`. Otherwise `value is `false`. +/// True if `T` is derived from `Field2D`, otherwise false +template +inline constexpr bool is_Field2D_v = std::is_base_of_v; + template using is_Field3D = std::is_base_of; -/// If `T` is derived from `FieldPerp`, provides the member constant -/// `value` equal to `true`. Otherwise `value is `false`. +/// True if `T` is derived from `Field3D`, otherwise false +template +inline constexpr bool is_Field3D_v = std::is_base_of_v; + template using is_FieldPerp = std::is_base_of; -/// If `T` is derived from `Options`, provides the member constant -/// `value` equal to `true`. Otherwise `value is `false`. +/// True if `T` is derived from `FieldPerp`, otherwise false +template +inline constexpr bool is_FieldPerp_v = std::is_base_of_v; + template using is_Options = std::is_base_of; +/// True if `T` is derived from `Options`, otherwise false +template +inline constexpr bool is_Options_v = std::is_base_of_v; + /// Enable a function if all the Ts are subclasses of `Field`, and /// returns the common type: i.e. `Field3D` if at least one argument /// is `Field3D`, otherwise `Field2D` if they are all `Field2D` @@ -104,33 +89,29 @@ using is_Options = std::is_base_of; /// `Field2D` if `V` is `Field2D`, and `Field3D` if `V` is `Field3D`. template using EnableIfField = - typename std::enable_if::value...), - typename std::common_type::type>::type; + std::enable_if_t<(is_Field_v and ...), std::common_type_t>; /// Enable a function if all the Ts are subclasses of `Field2D`, and /// returns the common type template using EnableIfField2D = - typename std::enable_if::value...), - typename std::common_type::type>::type; + std::enable_if_t<(is_Field2D_v and ...), std::common_type_t>; /// Enable a function if all the Ts are subclasses of `Field3D`, and /// returns the common type template using EnableIfField3D = - typename std::enable_if::value...), - typename std::common_type::type>::type; + std::enable_if_t<(is_Field3D_v and ...), std::common_type_t>; /// Enable a function if all the Ts are subclasses of `FieldPerp`, and /// returns the common type template using EnableIfFieldPerp = - typename std::enable_if::value...), - typename std::common_type::type>::type; + std::enable_if_t<(is_FieldPerp_v and ...), std::common_type_t>; /// Enable a function if T is a subclass of Options template -using EnableIfOptions = std::enable_if_t::value>; +using EnableIfOptions = std::enable_if_t>; } // namespace utils } // namespace bout diff --git a/include/bout/unused.hxx b/include/bout/unused.hxx index 6e7a46c7c0..7ef67cfe84 100644 --- a/include/bout/unused.hxx +++ b/include/bout/unused.hxx @@ -1,5 +1,5 @@ -#ifndef __UNUSED_H__ -#define __UNUSED_H__ +#ifndef BOUT_UNUSED_H +#define BOUT_UNUSED_H /// Mark a function parameter as unused in the function body /// @@ -37,24 +37,4 @@ #define UNUSED(x) x #endif -/// Mark a function parameter as possibly unused in the function body -/// -/// Unlike `UNUSED`, this has to go around the type as well: -/// -/// MAYBE_UNUSED(int foo); -#ifdef __has_cpp_attribute -#if __has_cpp_attribute(maybe_unused) -#define MAYBE_UNUSED(x) [[maybe_unused]] x -#endif -#endif -#ifndef MAYBE_UNUSED -#if defined(__GNUC__) -#define MAYBE_UNUSED(x) [[gnu::unused]] x -#elif defined(_MSC_VER) -#define MAYBE_UNUSED(x) __pragma(warning(suppress : 4100)) x -#else -#define MAYBE_UNUSED(x) x -#endif -#endif - -#endif //__UNUSED_H__ +#endif //BOUT_UNUSED_H diff --git a/include/bout/utils.hxx b/include/bout/utils.hxx index 450d3eaf87..b45152fbcc 100644 --- a/include/bout/utils.hxx +++ b/include/bout/utils.hxx @@ -26,8 +26,8 @@ * **************************************************************************/ -#ifndef __UTILS_H__ -#define __UTILS_H__ +#ifndef BOUT_UTILS_H +#define BOUT_UTILS_H #include "bout/bout_types.hxx" #include "bout/boutexception.hxx" @@ -37,6 +37,7 @@ #include "bout/assert.hxx" #include "bout/build_config.hxx" #include "bout/msg_stack.hxx" +#include "bout/region.hxx" #include "bout/unused.hxx" #include @@ -105,7 +106,7 @@ struct function_traits; /// bout::utils::function_traits::arg<1>::type; /// // The following prints "true": /// std::cout << std::boolalpha -/// << std::is_same::value; +/// << std::is_same_v; /// /// Adapted from https://stackoverflow.com/a/9065203/2043465 template @@ -204,6 +205,8 @@ public: using size_type = int; Matrix() = default; + Matrix(Matrix&&) noexcept = default; + Matrix& operator=(Matrix&&) noexcept = default; Matrix(size_type n1, size_type n2) : n1(n1), n2(n2) { ASSERT2(n1 >= 0); ASSERT2(n2 >= 0); @@ -214,6 +217,7 @@ public: // Prevent copy on write for Matrix data.ensureUnique(); } + ~Matrix() = default; /// Reallocate the Matrix to shape \p new_size_1 by \p new_size_2 /// @@ -298,6 +302,8 @@ public: using size_type = int; Tensor() = default; + Tensor(Tensor&&) noexcept = default; + Tensor& operator=(Tensor&&) noexcept = default; Tensor(size_type n1, size_type n2, size_type n3) : n1(n1), n2(n2), n3(n3) { ASSERT2(n1 >= 0); ASSERT2(n2 >= 0); @@ -309,6 +315,7 @@ public: // Prevent copy on write for Tensor data.ensureUnique(); } + ~Tensor() = default; /// Reallocate the Tensor with shape \p new_size_1 by \p new_size_2 by \p new_size_3 /// @@ -347,6 +354,22 @@ public: return data[(i1 * n2 + i2) * n3 + i3]; } + const T& operator[](Ind3D i) const { + // ny and nz are private :-( + // ASSERT2(i.nz == n3); + // ASSERT2(i.ny == n2); + ASSERT2(0 <= i.ind && i.ind < n1 * n2 * n3); + return data[i.ind]; + } + + T& operator[](Ind3D i) { + // ny and nz are private :-( + // ASSERT2(i.nz == n3); + // ASSERT2(i.ny == n2); + ASSERT2(0 <= i.ind && i.ind < n1 * n2 * n3); + return data[i.ind]; + } + Tensor& operator=(const T& val) { for (auto& i : data) { i = val; @@ -690,4 +713,11 @@ T* pointer(T& val) { #define BOUT_CONCAT(A, B) BOUT_CONCAT_(A, B) #endif -#endif // __UTILS_H__ +namespace bout { +namespace utils { +/// Check that \p flag is set in \p bitset +inline bool flagSet(int bitset, int flag) { return (bitset & flag) != 0; } +} // namespace utils +} // namespace bout + +#endif // BOUT_UTILS_H diff --git a/include/bout/vecops.hxx b/include/bout/vecops.hxx index 4a03d06b5e..9166503855 100644 --- a/include/bout/vecops.hxx +++ b/include/bout/vecops.hxx @@ -26,8 +26,8 @@ * **************************************************************************/ -#ifndef __VECOPS_H__ -#define __VECOPS_H__ +#ifndef BOUT_VECOPS_H +#define BOUT_VECOPS_H #include "bout/bout_types.hxx" #include "bout/coordinates.hxx" @@ -129,4 +129,4 @@ Vector3D V_dot_Grad(const Vector2D& v, const Vector3D& a); Vector3D V_dot_Grad(const Vector3D& v, const Vector2D& a); Vector3D V_dot_Grad(const Vector3D& v, const Vector3D& a); -#endif // __VECOPS_H__ +#endif // BOUT_VECOPS_H diff --git a/include/bout/vector2d.hxx b/include/bout/vector2d.hxx index 9ff4a69ba8..bdc375e698 100644 --- a/include/bout/vector2d.hxx +++ b/include/bout/vector2d.hxx @@ -34,12 +34,12 @@ class Vector2D; #pragma once -#ifndef __VECTOR2D_H__ -#define __VECTOR2D_H__ +#ifndef BOUT_VECTOR2D_H +#define BOUT_VECTOR2D_H class Field2D; class Field3D; -class Vector3D; //#include "bout/vector3d.hxx" +class Vector3D; #include @@ -217,4 +217,4 @@ inline Vector2D zeroFrom(const Vector2D& v) { */ inline Vector2D& ddt(Vector2D& f) { return *(f.timeDeriv()); } -#endif // __VECTOR2D_H__ +#endif // BOUT_VECTOR2D_H diff --git a/include/bout/vector3d.hxx b/include/bout/vector3d.hxx index f3adf41ae8..0c71dcffa5 100644 --- a/include/bout/vector3d.hxx +++ b/include/bout/vector3d.hxx @@ -30,14 +30,13 @@ class Vector3D; #pragma once -#ifndef __VECTOR3D_H__ -#define __VECTOR3D_H__ +#ifndef BOUT_VECTOR3D_H +#define BOUT_VECTOR3D_H -class Field2D; //#include "bout/field2d.hxx" +class Field2D; +class Vector2D; #include "bout/field3d.hxx" -class Vector2D; //#include "bout/vector2d.hxx" - /*! * Represents a 3D vector, with x,y,z components * stored as separate Field3D objects @@ -238,4 +237,4 @@ inline Vector3D zeroFrom(const Vector3D& v) { */ inline Vector3D& ddt(Vector3D& f) { return *(f.timeDeriv()); } -#endif // __VECTOR3D_H__ +#endif // BOUT_VECTOR3D_H diff --git a/include/bout/version.hxx.in b/include/bout/version.hxx.in index 06a32808af..3eaf40dbd7 100644 --- a/include/bout/version.hxx.in +++ b/include/bout/version.hxx.in @@ -5,22 +5,20 @@ #ifndef BOUT_VERSION_H #define BOUT_VERSION_H -// TODO: Make these all `inline` when we upgrade to C++17 - namespace bout { namespace version { /// The full version number -constexpr auto full = "@BOUT_VERSION@"; +inline constexpr auto full = "@BOUT_VERSION@"; /// The major version number -constexpr int major = @BOUT_VERSION_MAJOR@; +inline constexpr int major = @BOUT_VERSION_MAJOR@; /// The minor version number -constexpr int minor = @BOUT_VERSION_MINOR@; +inline constexpr int minor = @BOUT_VERSION_MINOR@; /// The patch version number -constexpr int patch = @BOUT_VERSION_PATCH@; +inline constexpr int patch = @BOUT_VERSION_PATCH@; /// The version pre-release identifier -constexpr auto prerelease = "@BOUT_VERSION_TAG@"; +inline constexpr auto prerelease = "@BOUT_VERSION_TAG@"; /// The full version number as a double -constexpr double as_double = @BOUT_VERSION_MAJOR@.@BOUT_VERSION_MINOR@@BOUT_VERSION_PATCH@; +inline constexpr double as_double = @BOUT_VERSION_MAJOR@.@BOUT_VERSION_MINOR@@BOUT_VERSION_PATCH@; } // namespace version } // namespace bout diff --git a/include/bout/where.hxx b/include/bout/where.hxx index 504dc028b1..c798d75de8 100644 --- a/include/bout/where.hxx +++ b/include/bout/where.hxx @@ -25,8 +25,8 @@ * **************************************************************************/ -#ifndef __WHERE_H__ -#define __WHERE_H__ +#ifndef BOUT_WHERE_H +#define BOUT_WHERE_H #include "bout/field.hxx" #include "bout/field2d.hxx" @@ -85,4 +85,4 @@ auto where(const T& test, BoutReal gt0, BoutReal le0) -> ResultType { return result; } -#endif // __WHERE_H__ +#endif // BOUT_WHERE_H diff --git a/m4/ax_append_compile_flags.m4 b/m4/ax_append_compile_flags.m4 deleted file mode 100644 index 5b6f1af51d..0000000000 --- a/m4/ax_append_compile_flags.m4 +++ /dev/null @@ -1,67 +0,0 @@ -# ============================================================================ -# https://www.gnu.org/software/autoconf-archive/ax_append_compile_flags.html -# ============================================================================ -# -# SYNOPSIS -# -# AX_APPEND_COMPILE_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT]) -# -# DESCRIPTION -# -# For every FLAG1, FLAG2 it is checked whether the compiler works with the -# flag. If it does, the flag is added FLAGS-VARIABLE -# -# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. -# CFLAGS) is used. During the check the flag is always added to the -# current language's flags. -# -# If EXTRA-FLAGS is defined, it is added to the current language's default -# flags (e.g. CFLAGS) when the check is done. The check is thus made with -# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to -# force the compiler to issue an error when a bad flag is given. -# -# INPUT gives an alternative input source to AC_COMPILE_IFELSE. -# -# NOTE: This macro depends on the AX_APPEND_FLAG and -# AX_CHECK_COMPILE_FLAG. Please keep this macro in sync with -# AX_APPEND_LINK_FLAGS. -# -# LICENSE -# -# Copyright (c) 2011 Maarten Bosmans -# -# This program 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. -# -# This program 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 this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 6 - -AC_DEFUN([AX_APPEND_COMPILE_FLAGS], -[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG]) -AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) -for flag in $1; do - AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3], [$4]) -done -])dnl AX_APPEND_COMPILE_FLAGS diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 deleted file mode 100644 index e8c5312af6..0000000000 --- a/m4/ax_append_flag.m4 +++ /dev/null @@ -1,71 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) -# -# DESCRIPTION -# -# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space -# added in between. -# -# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. -# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains -# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly -# FLAG. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2011 Maarten Bosmans -# -# This program 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. -# -# This program 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 this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 7 - -AC_DEFUN([AX_APPEND_FLAG], -[dnl -AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF -AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) -AS_VAR_SET_IF(FLAGS,[ - AS_CASE([" AS_VAR_GET(FLAGS) "], - [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], - [ - AS_VAR_APPEND(FLAGS,[" $1"]) - AC_RUN_LOG([: FLAGS="$FLAGS"]) - ]) - ], - [ - AS_VAR_SET(FLAGS,[$1]) - AC_RUN_LOG([: FLAGS="$FLAGS"]) - ]) -AS_VAR_POPDEF([FLAGS])dnl -])dnl AX_APPEND_FLAG diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 deleted file mode 100644 index dcabb92a14..0000000000 --- a/m4/ax_check_compile_flag.m4 +++ /dev/null @@ -1,74 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) -# -# DESCRIPTION -# -# Check whether the given FLAG works with the current language's compiler -# or gives an error. (Warnings, however, are ignored) -# -# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on -# success/failure. -# -# If EXTRA-FLAGS is defined, it is added to the current language's default -# flags (e.g. CFLAGS) when the check is done. The check is thus made with -# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to -# force the compiler to issue an error when a bad flag is given. -# -# INPUT gives an alternative input source to AC_COMPILE_IFELSE. -# -# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this -# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. -# -# LICENSE -# -# Copyright (c) 2008 Guido U. Draheim -# Copyright (c) 2011 Maarten Bosmans -# -# This program 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. -# -# This program 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 this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 5 - -AC_DEFUN([AX_CHECK_COMPILE_FLAG], -[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF -AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl -AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ - ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS - _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" - AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], - [AS_VAR_SET(CACHEVAR,[yes])], - [AS_VAR_SET(CACHEVAR,[no])]) - _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) -AS_VAR_IF(CACHEVAR,yes, - [m4_default([$2], :)], - [m4_default([$3], :)]) -AS_VAR_POPDEF([CACHEVAR])dnl -])dnl AX_CHECK_COMPILE_FLAGS diff --git a/m4/ax_code_coverage.m4 b/m4/ax_code_coverage.m4 deleted file mode 100644 index 7a5b742b44..0000000000 --- a/m4/ax_code_coverage.m4 +++ /dev/null @@ -1,241 +0,0 @@ -# =========================================================================== -# This was modified for the BOUT++ project -# Original from: -# https://www.gnu.org/software/autoconf-archive/ax_code_coverage.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CODE_COVERAGE() -# -# DESCRIPTION -# -# Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS, -# CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LIBS which should be included -# in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LIBADD variables of every -# build target (program or library) which should be built with code -# coverage support. Also defines CODE_COVERAGE_RULES which should be -# substituted in your Makefile; and $enable_code_coverage which can be -# used in subsequent configure output. CODE_COVERAGE_ENABLED is defined -# and substituted, and corresponds to the value of the -# --enable-code-coverage option, which defaults to being disabled. -# -# Test also for gcov program and create GCOV variable that could be -# substituted. -# -# Note that all optimization flags in CFLAGS must be disabled when code -# coverage is enabled. -# -# Usage example: -# -# configure.ac: -# -# AX_CODE_COVERAGE -# -# Makefile.am: -# -# @CODE_COVERAGE_RULES@ -# my_program_LIBS = ... $(CODE_COVERAGE_LIBS) ... -# my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ... -# my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ... -# my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ... -# -# This results in a "check-code-coverage" rule being added to any -# Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module -# has been configured with --enable-code-coverage). Running `make -# check-code-coverage` in that directory will run the module's test suite -# (`make check`) and build a code coverage report detailing the code which -# was touched, then print the URI for the report. -# -# In earlier versions of this macro, CODE_COVERAGE_LDFLAGS was defined -# instead of CODE_COVERAGE_LIBS. They are both still defined, but use of -# CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is -# deprecated. They have the same value. -# -# This code was derived from Makefile.decl in GLib, originally licenced -# under LGPLv2.1+. -# -# LICENSE -# -# Copyright (c) 2012, 2016 Philip Withnall -# Copyright (c) 2012 Xan Lopez -# Copyright (c) 2012 Christian Persch -# Copyright (c) 2012 Paolo Borelli -# Copyright (c) 2012 Dan Winship -# Copyright (c) 2015 Bastien ROUCARIES -# -# This library is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or (at -# your option) any later version. -# -# This library 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 Lesser -# General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this program. If not, see . - -#serial 24 - -AC_DEFUN([AX_CODE_COVERAGE],[ - dnl Check for --enable-code-coverage - AC_REQUIRE([AC_PROG_SED]) - - # allow to override gcov location - AC_ARG_WITH([gcov], - [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])], - [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov], - [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov]) - - AC_MSG_CHECKING([whether to build with code coverage support]) - AC_ARG_ENABLE([code-coverage], - AS_HELP_STRING([--enable-code-coverage], - [Whether to enable code coverage support]),, - enable_code_coverage=no) - - AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) - AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) - AC_MSG_RESULT($enable_code_coverage) - - AS_IF([ test "$enable_code_coverage" = "yes" ], [ - # check for gcov - AC_CHECK_TOOL([GCOV], - [$_AX_CODE_COVERAGE_GCOV_PROG_WITH], - [:]) - AS_IF([test "X$GCOV" = "X:"], - [AC_MSG_ERROR([gcov is needed to do coverage])]) - AC_SUBST([GCOV]) - - dnl Check if gcc is being used - AS_IF([ test "$GCC" = "no" ], [ - AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) - ]) - - AC_CHECK_PROG([LCOV], [lcov], [lcov]) - AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) - - AS_IF([ test -z "$LCOV" ], [ - AC_MSG_ERROR([To enable code coverage reporting you must have lcov installed]) - ]) - - AS_IF([ test -z "$GENHTML" ], [ - AC_MSG_ERROR([Could not find genhtml from the lcov package]) - ]) - - dnl Build the code coverage flags - dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility - CODE_COVERAGE_CPPFLAGS="-DNDEBUG" - CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_LIBS="-lgcov" - CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS" - - AC_SUBST([CODE_COVERAGE_CPPFLAGS]) - AC_SUBST([CODE_COVERAGE_CFLAGS]) - AC_SUBST([CODE_COVERAGE_CXXFLAGS]) - AC_SUBST([CODE_COVERAGE_LIBS]) - AC_SUBST([CODE_COVERAGE_LDFLAGS]) - - [CODE_COVERAGE_RULES_CAPTURE=' - @$(LCOV) --quiet $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --no-external --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --no-checksum $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS) - @$(LCOV) --quiet $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS) - -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp - @LANG=C $(GENHTML) --quiet $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --demangle-cpp --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "BOUT++ Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) - @$(LCOV) --summary $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_LCOV_OPTIONS) - @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" -'] - [CODE_COVERAGE_RULES_CLEAN=' -clean:: code-coverage-clean -distclean:: code-coverage-clean -code-coverage-clean: - -@$(LCOV) --directory $(abs_builddir) -z --quiet - -@$(RM) -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -@find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete -'] - ], [ - [CODE_COVERAGE_RULES_CHECK=' - @echo "Need to reconfigure with --enable-code-coverage" -'] - CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK" - CODE_COVERAGE_RULES_CLEAN='' - ]) - -[CODE_COVERAGE_RULES=' -# Code coverage -# -# Optional: -# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. -# Multiple directories may be specified, separated by whitespace. -# (Default: $(top_builddir)) -# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated -# by lcov for code coverage. (Default: -# bout-coverage.info) -# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage -# reports to be created. (Default: -# bout-coverage) -# - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, -# set to 0 to disable it and leave empty to stay with the default. -# (Default: empty) -# - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov -# instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) -# - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov -# instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) -# - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov -# - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the -# collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) -# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov -# instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) -# - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering -# lcov instance. (Default: empty) -# - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov -# instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) -# - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the -# genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) -# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml -# instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) -# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore -# -# The generated report will be titled using the $(PACKAGE_NAME) and -# $(PACKAGE_VERSION). In order to add the current git hash to the title, -# use the git-version-gen script, available online. - -# Optional variables -CODE_COVERAGE_DIRECTORY ?= $(abs_builddir) -CODE_COVERAGE_OUTPUT_FILE ?= bout-coverage.info -CODE_COVERAGE_OUTPUT_DIRECTORY ?= bout-coverage -CODE_COVERAGE_BRANCH_COVERAGE ?= -CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ---rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) -CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) -CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" -CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) -CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) -CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= -CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) -CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ -$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ ---rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) -CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) -CODE_COVERAGE_IGNORE_PATTERN ?= "*test*/*" - -# Use recursive makes in order to ignore errors during check -check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"' - -# Capture code coverage data -code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"' - -# Hook rule executed before code-coverage-capture, overridable by the user -code-coverage-capture-hook: - -'"$CODE_COVERAGE_RULES_CLEAN"' - -GITIGNOREFILES ?= -GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean -'] - - AC_SUBST([CODE_COVERAGE_RULES]) -]) diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 deleted file mode 100644 index 43087b2e68..0000000000 --- a/m4/ax_cxx_compile_stdcxx.m4 +++ /dev/null @@ -1,951 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) -# -# DESCRIPTION -# -# Check for baseline language coverage in the compiler for the specified -# version of the C++ standard. If necessary, add switches to CXX and -# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) -# or '14' (for the C++14 standard). -# -# The second argument, if specified, indicates whether you insist on an -# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. -# -std=c++11). If neither is specified, you get whatever works, with -# preference for an extended mode. -# -# The third argument, if specified 'mandatory' or if left unspecified, -# indicates that baseline support for the specified C++ standard is -# required and that the macro should error out if no mode with that -# support is found. If specified 'optional', then configuration proceeds -# regardless, after defining HAVE_CXX${VERSION} if and only if a -# supporting mode is found. -# -# LICENSE -# -# Copyright (c) 2008 Benjamin Kosnik -# Copyright (c) 2012 Zack Weinberg -# Copyright (c) 2013 Roy Stogner -# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov -# Copyright (c) 2015 Paul Norman -# Copyright (c) 2015 Moritz Klammler -# Copyright (c) 2016, 2018 Krzesimir Nowak -# Copyright (c) 2019 Enji Cooper -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 11 - -dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro -dnl (serial version number 13). - -AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl - m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], - [$1], [14], [ax_cxx_compile_alternatives="14 1y"], - [$1], [17], [ax_cxx_compile_alternatives="17 1z"], - [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl - m4_if([$2], [], [], - [$2], [ext], [], - [$2], [noext], [], - [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl - m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], - [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], - [$3], [optional], [ax_cxx_compile_cxx$1_required=false], - [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) - AC_LANG_PUSH([C++])dnl - ac_success=no - - m4_if([$2], [noext], [], [dnl - if test x$ac_success = xno; then - for alternative in ${ax_cxx_compile_alternatives}; do - switch="-std=gnu++${alternative}" - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, - $cachevar, - [ac_save_CXX="$CXX" - CXX="$CXX $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXX="$ac_save_CXX"]) - if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" - fi - ac_success=yes - break - fi - done - fi]) - - m4_if([$2], [ext], [], [dnl - if test x$ac_success = xno; then - dnl HP's aCC needs +std=c++11 according to: - dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf - dnl Cray's crayCC needs "-h std=c++11" - for alternative in ${ax_cxx_compile_alternatives}; do - for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, - $cachevar, - [ac_save_CXX="$CXX" - CXX="$CXX $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXX="$ac_save_CXX"]) - if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" - fi - ac_success=yes - break - fi - done - if test x$ac_success = xyes; then - break - fi - done - fi]) - AC_LANG_POP([C++]) - if test x$ax_cxx_compile_cxx$1_required = xtrue; then - if test x$ac_success = xno; then - AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) - fi - fi - if test x$ac_success = xno; then - HAVE_CXX$1=0 - AC_MSG_NOTICE([No compiler with C++$1 support was found]) - else - HAVE_CXX$1=1 - AC_DEFINE(HAVE_CXX$1,1, - [define if the compiler supports basic C++$1 syntax]) - fi - AC_SUBST(HAVE_CXX$1) -]) - - -dnl Test body for checking C++11 support - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], - _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 -) - - -dnl Test body for checking C++14 support - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], - _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 - _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 -) - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], - _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 - _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 - _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 -) - -dnl Tests for new features in C++11 - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ - -// If the compiler admits that it is not ready for C++11, why torture it? -// Hopefully, this will speed up the test. - -#ifndef __cplusplus - -#error "This is not a C++ compiler" - -#elif __cplusplus < 201103L - -#error "This is not a C++11 compiler" - -#else - -namespace cxx11 -{ - - namespace test_static_assert - { - - template - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); - }; - - } - - namespace test_final_override - { - - struct Base - { - virtual ~Base() {} - virtual void f() {} - }; - - struct Derived : public Base - { - virtual ~Derived() override {} - virtual void f() override {} - }; - - } - - namespace test_double_right_angle_brackets - { - - template < typename T > - struct check {}; - - typedef check single_type; - typedef check> double_type; - typedef check>> triple_type; - typedef check>>> quadruple_type; - - } - - namespace test_decltype - { - - int - f() - { - int a = 1; - decltype(a) b = 2; - return a + b; - } - - } - - namespace test_type_deduction - { - - template < typename T1, typename T2 > - struct is_same - { - static const bool value = false; - }; - - template < typename T > - struct is_same - { - static const bool value = true; - }; - - template < typename T1, typename T2 > - auto - add(T1 a1, T2 a2) -> decltype(a1 + a2) - { - return a1 + a2; - } - - int - test(const int c, volatile int v) - { - static_assert(is_same::value == true, ""); - static_assert(is_same::value == false, ""); - static_assert(is_same::value == false, ""); - auto ac = c; - auto av = v; - auto sumi = ac + av + 'x'; - auto sumf = ac + av + 1.0; - static_assert(is_same::value == true, ""); - static_assert(is_same::value == true, ""); - static_assert(is_same::value == true, ""); - static_assert(is_same::value == false, ""); - static_assert(is_same::value == true, ""); - return (sumf > 0.0) ? sumi : add(c, v); - } - - } - - namespace test_noexcept - { - - int f() { return 0; } - int g() noexcept { return 0; } - - static_assert(noexcept(f()) == false, ""); - static_assert(noexcept(g()) == true, ""); - - } - - namespace test_constexpr - { - - template < typename CharT > - unsigned long constexpr - strlen_c_r(const CharT *const s, const unsigned long acc) noexcept - { - return *s ? strlen_c_r(s + 1, acc + 1) : acc; - } - - template < typename CharT > - unsigned long constexpr - strlen_c(const CharT *const s) noexcept - { - return strlen_c_r(s, 0UL); - } - - static_assert(strlen_c("") == 0UL, ""); - static_assert(strlen_c("1") == 1UL, ""); - static_assert(strlen_c("example") == 7UL, ""); - static_assert(strlen_c("another\0example") == 7UL, ""); - - } - - namespace test_rvalue_references - { - - template < int N > - struct answer - { - static constexpr int value = N; - }; - - answer<1> f(int&) { return answer<1>(); } - answer<2> f(const int&) { return answer<2>(); } - answer<3> f(int&&) { return answer<3>(); } - - void - test() - { - int i = 0; - const int c = 0; - static_assert(decltype(f(i))::value == 1, ""); - static_assert(decltype(f(c))::value == 2, ""); - static_assert(decltype(f(0))::value == 3, ""); - } - - } - - namespace test_uniform_initialization - { - - struct test - { - static const int zero {}; - static const int one {1}; - }; - - static_assert(test::zero == 0, ""); - static_assert(test::one == 1, ""); - - } - - namespace test_lambdas - { - - void - test1() - { - auto lambda1 = [](){}; - auto lambda2 = lambda1; - lambda1(); - lambda2(); - } - - int - test2() - { - auto a = [](int i, int j){ return i + j; }(1, 2); - auto b = []() -> int { return '0'; }(); - auto c = [=](){ return a + b; }(); - auto d = [&](){ return c; }(); - auto e = [a, &b](int x) mutable { - const auto identity = [](int y){ return y; }; - for (auto i = 0; i < a; ++i) - a += b--; - return x + identity(a + b); - }(0); - return a + b + c + d + e; - } - - int - test3() - { - const auto nullary = [](){ return 0; }; - const auto unary = [](int x){ return x; }; - using nullary_t = decltype(nullary); - using unary_t = decltype(unary); - const auto higher1st = [](nullary_t f){ return f(); }; - const auto higher2nd = [unary](nullary_t f1){ - return [unary, f1](unary_t f2){ return f2(unary(f1())); }; - }; - return higher1st(nullary) + higher2nd(nullary)(unary); - } - - } - - namespace test_variadic_templates - { - - template - struct sum; - - template - struct sum - { - static constexpr auto value = N0 + sum::value; - }; - - template <> - struct sum<> - { - static constexpr auto value = 0; - }; - - static_assert(sum<>::value == 0, ""); - static_assert(sum<1>::value == 1, ""); - static_assert(sum<23>::value == 23, ""); - static_assert(sum<1, 2>::value == 3, ""); - static_assert(sum<5, 5, 11>::value == 21, ""); - static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); - - } - - // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae - // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function - // because of this. - namespace test_template_alias_sfinae - { - - struct foo {}; - - template - using member = typename T::member_type; - - template - void func(...) {} - - template - void func(member*) {} - - void test(); - - void test() { func(0); } - - } - -} // namespace cxx11 - -#endif // __cplusplus >= 201103L - -]]) - - -dnl Tests for new features in C++14 - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ - -// If the compiler admits that it is not ready for C++14, why torture it? -// Hopefully, this will speed up the test. - -#ifndef __cplusplus - -#error "This is not a C++ compiler" - -#elif __cplusplus < 201402L - -#error "This is not a C++14 compiler" - -#else - -namespace cxx14 -{ - - namespace test_polymorphic_lambdas - { - - int - test() - { - const auto lambda = [](auto&&... args){ - const auto istiny = [](auto x){ - return (sizeof(x) == 1UL) ? 1 : 0; - }; - const int aretiny[] = { istiny(args)... }; - return aretiny[0]; - }; - return lambda(1, 1L, 1.0f, '1'); - } - - } - - namespace test_binary_literals - { - - constexpr auto ivii = 0b0000000000101010; - static_assert(ivii == 42, "wrong value"); - - } - - namespace test_generalized_constexpr - { - - template < typename CharT > - constexpr unsigned long - strlen_c(const CharT *const s) noexcept - { - auto length = 0UL; - for (auto p = s; *p; ++p) - ++length; - return length; - } - - static_assert(strlen_c("") == 0UL, ""); - static_assert(strlen_c("x") == 1UL, ""); - static_assert(strlen_c("test") == 4UL, ""); - static_assert(strlen_c("another\0test") == 7UL, ""); - - } - - namespace test_lambda_init_capture - { - - int - test() - { - auto x = 0; - const auto lambda1 = [a = x](int b){ return a + b; }; - const auto lambda2 = [a = lambda1(x)](){ return a; }; - return lambda2(); - } - - } - - namespace test_digit_separators - { - - constexpr auto ten_million = 100'000'000; - static_assert(ten_million == 100000000, ""); - - } - - namespace test_return_type_deduction - { - - auto f(int& x) { return x; } - decltype(auto) g(int& x) { return x; } - - template < typename T1, typename T2 > - struct is_same - { - static constexpr auto value = false; - }; - - template < typename T > - struct is_same - { - static constexpr auto value = true; - }; - - int - test() - { - auto x = 0; - static_assert(is_same::value, ""); - static_assert(is_same::value, ""); - return x; - } - - } - -} // namespace cxx14 - -#endif // __cplusplus >= 201402L - -]]) - - -dnl Tests for new features in C++17 - -m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ - -// If the compiler admits that it is not ready for C++17, why torture it? -// Hopefully, this will speed up the test. - -#ifndef __cplusplus - -#error "This is not a C++ compiler" - -#elif __cplusplus < 201703L - -#error "This is not a C++17 compiler" - -#else - -#include -#include -#include - -namespace cxx17 -{ - - namespace test_constexpr_lambdas - { - - constexpr int foo = [](){return 42;}(); - - } - - namespace test::nested_namespace::definitions - { - - } - - namespace test_fold_expression - { - - template - int multiply(Args... args) - { - return (args * ... * 1); - } - - template - bool all(Args... args) - { - return (args && ...); - } - - } - - namespace test_extended_static_assert - { - - static_assert (true); - - } - - namespace test_auto_brace_init_list - { - - auto foo = {5}; - auto bar {5}; - - static_assert(std::is_same, decltype(foo)>::value); - static_assert(std::is_same::value); - } - - namespace test_typename_in_template_template_parameter - { - - template typename X> struct D; - - } - - namespace test_fallthrough_nodiscard_maybe_unused_attributes - { - - int f1() - { - return 42; - } - - [[nodiscard]] int f2() - { - [[maybe_unused]] auto unused = f1(); - - switch (f1()) - { - case 17: - f1(); - [[fallthrough]]; - case 42: - f1(); - } - return f1(); - } - - } - - namespace test_extended_aggregate_initialization - { - - struct base1 - { - int b1, b2 = 42; - }; - - struct base2 - { - base2() { - b3 = 42; - } - int b3; - }; - - struct derived : base1, base2 - { - int d; - }; - - derived d1 {{1, 2}, {}, 4}; // full initialization - derived d2 {{}, {}, 4}; // value-initialized bases - - } - - namespace test_general_range_based_for_loop - { - - struct iter - { - int i; - - int& operator* () - { - return i; - } - - const int& operator* () const - { - return i; - } - - iter& operator++() - { - ++i; - return *this; - } - }; - - struct sentinel - { - int i; - }; - - bool operator== (const iter& i, const sentinel& s) - { - return i.i == s.i; - } - - bool operator!= (const iter& i, const sentinel& s) - { - return !(i == s); - } - - struct range - { - iter begin() const - { - return {0}; - } - - sentinel end() const - { - return {5}; - } - }; - - void f() - { - range r {}; - - for (auto i : r) - { - [[maybe_unused]] auto v = i; - } - } - - } - - namespace test_lambda_capture_asterisk_this_by_value - { - - struct t - { - int i; - int foo() - { - return [*this]() - { - return i; - }(); - } - }; - - } - - namespace test_enum_class_construction - { - - enum class byte : unsigned char - {}; - - byte foo {42}; - - } - - namespace test_constexpr_if - { - - template - int f () - { - if constexpr(cond) - { - return 13; - } - else - { - return 42; - } - } - - } - - namespace test_selection_statement_with_initializer - { - - int f() - { - return 13; - } - - int f2() - { - if (auto i = f(); i > 0) - { - return 3; - } - - switch (auto i = f(); i + 4) - { - case 17: - return 2; - - default: - return 1; - } - } - - } - - namespace test_template_argument_deduction_for_class_templates - { - - template - struct pair - { - pair (T1 p1, T2 p2) - : m1 {p1}, - m2 {p2} - {} - - T1 m1; - T2 m2; - }; - - void f() - { - [[maybe_unused]] auto p = pair{13, 42u}; - } - - } - - namespace test_non_type_auto_template_parameters - { - - template - struct B - {}; - - B<5> b1; - B<'a'> b2; - - } - - namespace test_structured_bindings - { - - int arr[2] = { 1, 2 }; - std::pair pr = { 1, 2 }; - - auto f1() -> int(&)[2] - { - return arr; - } - - auto f2() -> std::pair& - { - return pr; - } - - struct S - { - int x1 : 2; - volatile double y1; - }; - - S f3() - { - return {}; - } - - auto [ x1, y1 ] = f1(); - auto& [ xr1, yr1 ] = f1(); - auto [ x2, y2 ] = f2(); - auto& [ xr2, yr2 ] = f2(); - const auto [ x3, y3 ] = f3(); - - } - - namespace test_exception_spec_type_system - { - - struct Good {}; - struct Bad {}; - - void g1() noexcept; - void g2(); - - template - Bad - f(T*, T*); - - template - Good - f(T1*, T2*); - - static_assert (std::is_same_v); - - } - - namespace test_inline_variables - { - - template void f(T) - {} - - template inline T g(T) - { - return T{}; - } - - template<> inline void f<>(int) - {} - - template<> int g<>(int) - { - return 5; - } - - } - -} // namespace cxx17 - -#endif // __cplusplus < 201703L - -]]) diff --git a/m4/ax_prog_cxx_mpi.m4 b/m4/ax_prog_cxx_mpi.m4 deleted file mode 100644 index 0199928f41..0000000000 --- a/m4/ax_prog_cxx_mpi.m4 +++ /dev/null @@ -1,175 +0,0 @@ -# =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_prog_cxx_mpi.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_PROG_CXX_MPI([MPI-WANTED-TEST[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]]) -# -# DESCRIPTION -# -# This macro tries to find out how to compile C++ programs that use MPI -# (Message Passing Interface), a standard API for parallel process -# communication (see http://www-unix.mcs.anl.gov/mpi/). The macro has to -# be used instead of the standard macro AC_PROG_CXX and will replace the -# standard variable CXX with the found compiler. -# -# MPI-WANTED-TEST is used to test whether MPI is actually wanted by the -# user. If MPI-WANTED_TEST is omitted or if it succeeds, the macro will -# try to find out how to use MPI, if it fails, the macro will call -# AC_PROG_CC to find a standard C compiler instead. -# -# When MPI is found, ACTION-IF-FOUND will be executed, if MPI is not found -# (or MPI-WANTED-TEST fails) ACTION-IF-NOT-FOUND is executed. If -# ACTION-IF-FOUND is not set, the macro will define HAVE_MPI. -# -# The following example demonstrates usage of the macro: -# -# # If --with-mpi=auto is used, try to find MPI, but use standard C compiler if it is not found. -# # If --with-mpi=yes is used, try to find MPI and fail if it isn't found. -# # If --with-mpi=no is used, use a standard C compiler instead. -# AC_ARG_WITH(mpi, [AS_HELP_STRING([--with-mpi], -# [compile with MPI (parallelization) support. If none is found, -# MPI is not used. Default: auto]) -# ],,[with_mpi=auto]) -# -# AX_PROG_CXX_MPI([test x"$with_mpi" != xno],[use_mpi=yes],[ -# use_mpi=no -# if test x"$with_mpi" = xyes; then -# AC_MSG_FAILURE([MPI compiler requested, but couldn't use MPI.]) -# else -# AC_MSG_WARN([No MPI compiler found, won't use MPI.]) -# fi -# ]) -# -# LICENSE -# -# Copyright (c) 2010,2011 Olaf Lenz -# -# This program 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. -# -# This program 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 this program. If not, see . -# -# As a special exception, the respective Autoconf Macro's copyright owner -# gives unlimited permission to copy, distribute and modify the configure -# scripts that are the output of Autoconf when processing the Macro. You -# need not follow the terms of the GNU General Public License when using -# or distributing such scripts, even though portions of the text of the -# Macro appear in them. The GNU General Public License (GPL) does govern -# all other use of the material that constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the Autoconf -# Macro released by the Autoconf Archive. When you make and distribute a -# modified version of the Autoconf Macro, you may extend this special -# exception to the GPL to apply to your modified version as well. - -#serial 2 - -AC_DEFUN([AX_PROG_CXX_MPI], [ -AC_PREREQ(2.50) - -# Check for compiler -# Needs to be split off into an extra macro to ensure right expansion -# order. -AC_REQUIRE([_AX_PROG_CXX_MPI],[_AX_PROG_CXX_MPI([$1])]) - -AS_IF([test x"$_ax_prog_cxx_mpi_mpi_wanted" = xno], - [ _ax_prog_cxx_mpi_mpi_found=no ], - [ - AC_LANG_PUSH([C++]) - - # test whether MPI_Init() is available - # We do not use AC_SEARCH_LIBS here, as it caches its outcome and - # thus disallows corresponding calls in the other AX_PROG_*_MPI - # macros. - for lib in NONE mpi mpich; do - save_LIBS=$LIBS - if test x"$lib" = xNONE; then - AC_MSG_CHECKING([for function MPI_Init]) - else - AC_MSG_CHECKING([for function MPI_Init in -l$lib]) - LIBS="-l$lib $LIBS" - fi - AC_LINK_IFELSE([ - AC_LANG_PROGRAM([ -extern "C" { void MPI_Init(); } -],[MPI_Init();])], - [ _ax_prog_cxx_mpi_mpi_found=yes ], - [ _ax_prog_cxx_mpi_mpi_found=no ]) - AC_MSG_RESULT($_ax_prog_cxx_mpi_mpi_found) - if test "x$_ax_prog_cxx_mpi_mpi_found" = "xyes"; then - break; - fi - LIBS=$save_LIBS - done - - # Check for header - AS_IF([test x"$_ax_prog_cxx_mpi_mpi_found" = xyes], [ - AC_MSG_CHECKING([for mpi.h]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include ])], - [ AC_MSG_RESULT(yes)], - [ AC_MSG_RESULT(no) - _ax_prog_cxx_mpi_mpi_found=no - ]) - ]) - AC_LANG_POP([C++]) -]) - -# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -AS_IF([test x"$_ax_prog_cxx_mpi_mpi_found" = xyes], [ - ifelse([$2],,[AC_DEFINE(HAVE_MPI,1,[Define if you have the MPI library.])],[$2]) - : -],[ - $3 - : -]) - -])dnl AX_PROG_CXX_MPI - -dnl _AX_PROG_CXX_MPI is an internal macro required by AX_PROG_CXX_MPI. -dnl To ensure the right expansion order, the main function AX_PROG_CXX_MPI -dnl has to be split into two parts. -dnl -dnl Known MPI C++ compilers: -dnl mpic++ -dnl mpicxx -dnl mpiCC -dnl sxmpic++ NEC SX -dnl hcp -dnl mpxlC_r -dnl mpxlC -dnl mpixlcxx_r -dnl mpixlcxx -dnl mpg++ -dnl mpc++ -dnl mpCC -dnl cmpic++ -dnl mpiFCC Fujitsu -dnl CC -dnl -AC_DEFUN([_AX_PROG_CXX_MPI], [ - AC_ARG_VAR(MPICXX,[MPI C++ compiler command]) - ifelse([$1],,[_ax_prog_cxx_mpi_mpi_wanted=yes],[ - AC_MSG_CHECKING([whether to compile using MPI]) - if $1; then - _ax_prog_cxx_mpi_mpi_wanted=yes - else - _ax_prog_cxx_mpi_mpi_wanted=no - fi - AC_MSG_RESULT($_ax_prog_cxx_mpi_mpi_wanted) - ]) - if test x"$_ax_prog_cxx_mpi_mpi_wanted" = xyes; then - AC_CHECK_TOOLS([MPICXX], [mpic++ mpicxx mpiCC sxmpic++ hcp mpxlC_r mpxlC mpixlcxx_r mpixlcxx mpg++ mpc++ mpCC cmpic++ mpiFCC CCicpc pgCC pathCC sxc++ xlC_r xlC bgxlC_r bgxlC openCC sunCC crayCC aCC CC g++ c++ gpp cxx cc++ cl.exe FCC KCC RCC]) - CXX="$MPICXX" - fi - AC_PROG_CXX -])dnl _AX_PROG_CXX_MPI diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4 deleted file mode 100644 index 17c3eab7da..0000000000 --- a/m4/ax_require_defined.m4 +++ /dev/null @@ -1,37 +0,0 @@ -# =========================================================================== -# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html -# =========================================================================== -# -# SYNOPSIS -# -# AX_REQUIRE_DEFINED(MACRO) -# -# DESCRIPTION -# -# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have -# been defined and thus are available for use. This avoids random issues -# where a macro isn't expanded. Instead the configure script emits a -# non-fatal: -# -# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found -# -# It's like AC_REQUIRE except it doesn't expand the required macro. -# -# Here's an example: -# -# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) -# -# LICENSE -# -# Copyright (c) 2014 Mike Frysinger -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 2 - -AC_DEFUN([AX_REQUIRE_DEFINED], [dnl - m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) -])dnl AX_REQUIRE_DEFINED diff --git a/m4/bout.m4 b/m4/bout.m4 deleted file mode 100644 index a2e5a8a733..0000000000 --- a/m4/bout.m4 +++ /dev/null @@ -1,306 +0,0 @@ -dnl -*- mode: autoconf -*- -dnl Copyright 2010-2016 B D Dudson, BOUT++ Team -dnl -dnl Contact Ben Dudson, bd512@york.ac.uk -dnl -dnl This file is part of BOUT++. -dnl -dnl BOUT++ is free software: you can redistribute it and/or modify -dnl it under the terms of the GNU Lesser General Public License as published by -dnl the Free Software Foundation, either version 3 of the License, or -dnl (at your option) any later version. -dnl -dnl BOUT++ is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public License -dnl along with BOUT++. If not, see . -dnl -dnl ------------------------------------------------------------ -dnl -dnl Additional macros for configure.ac -dnl Functions inspired by ESPResSo (espressomd.org) - -AC_DEFUN([BOUT_MSG_DEBUG],[ - dnl Uncomment line below to enable debugging - dnl AC_MSG_NOTICE([debug: $1]) - ]) - -dnl define the macro to check for libraries -dnl first argument is the name of the library -dnl second arg is a function of that library -dnl third arg is to be executed if found -dnl forth arg is to be executed if not found -dnl fifth arg is an additional path to check -AC_DEFUN([BOUT_ADDPATH_CHECK_LIB],[ - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - AC_MSG_CHECKING([for lib$1]) - AC_LANG_PUSH([C++]) - BACL_found=no - - # Try with no extra libraries first - AS_IF([test ."$5" = .yes], [extra_prefix=""], [extra_prefix="$5"]) - LIBS="$save_LIBS $EXTRA_LIBS" - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - extern "C" - char $2(); - ]], [[return $2();]])], - [BACL_found=yes - BOUT_MSG_DEBUG([found $1 without path or library flag])], - []) - LIBS=$save_LIBS - - # Now try with explicitly linking library - AS_IF([test $BACL_found != yes], [ - LIBS="$save_LIBS $EXTRA_LIBS -l$1" - AS_IF([test ."$5" = .yes], [extra_prefix=""], [extra_prefix="$5"]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - extern "C" - char $2(); - ]], [[return $2();]])], - [BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -l$1" - BOUT_MSG_DEBUG([found $1 without path])], - []) - ]) - - AS_IF([test $BACL_found != yes], [ - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local ; do - for path in $search_prefix $search_prefix/lib $search_prefix/lib64 $search_prefix/x86_64-linux-gnu - do - AS_IF([test -d $path], [ - LIBS="$save_LIBS $EXTRA_LIBS -l$1" - LDFLAGS="$save_LDFLAGS -L$path" - BOUT_MSG_DEBUG([try link $1 with $path]) - AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - extern "C" - char $2(); - ]], [[return $2();]])], - [BACL_found=yes - EXTRA_LIBS="$EXTRA_LIBS -L$path -l$1" - BOUT_MSG_DEBUG([found $1 with $path]) - break], - []) - ]) - done - AS_IF([test .$BACL_found = .yes],break;) - done - ]) - - AS_IF([test $BACL_found = yes], [ - AC_MSG_RESULT(yes) - ], [ - AC_MSG_RESULT(no) - ]) - - AS_IF([test $BACL_found = yes], [$3],[$4]) - - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS=$save_CPPFLAGS - AC_LANG_POP([C++]) -]) - - -dnl define the macro to check for header files -dnl first argument is the name of the header file -dnl secound arg is to be executed if found -dnl third arg is to be executed if not found -dnl forth arg is an additional path to check -AC_DEFUN([BOUT_ADDPATH_CHECK_HEADER],[ - AC_MSG_CHECKING([for $1]) - - save_CPPFLAGS=$CPPFLAGS - BACH_found=no - - AS_IF([test ."$4" != .yes], [extra_prefix="$4"], [extra_prefix=""]) - - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ - #include <$1> - ])], [BACH_found=yes - BOUT_MSG_DEBUG([found $1 without path]) - break]) - - AS_IF([test $BACH_found != yes], [ - for search_prefix in $extra_prefix /usr /opt $HOME $HOME/local /usr/local - do - for path in $search_prefix $search_prefix/include - do - AS_IF([test -d $path], [ - CPPFLAGS="$save_CPPFLAGS -I$path" - BOUT_MSG_DEBUG([try compile $1 with $path]) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([ - #include <$1> - ], [])], - [BACH_found=yes - EXTRA_INCS="$EXTRA_INCS -I$path" - BOUT_MSG_DEBUG([found $1 with $path]) - break]) - ]) - done - AS_IF([test .$BACH_found = .yes], [break;]) - done - ]) - - AS_IF([test $BACH_found = yes], [ - AC_MSG_RESULT(yes) - ], [ - AC_MSG_RESULT(no) - CPPFLAGS=$save_CPPFLAGS - ]) - AS_IF([test .$BACH_found = .yes], [$2], [$3]) -]) - -AC_DEFUN([BOUT_CHECK_PRETTYFUNCTION], [ - AC_LANG_PUSH([C++]) - AC_MSG_CHECKING([does C++ compiler support __PRETTY_FUNCTION__]) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[]], - [[const char* name = __PRETTY_FUNCTION__;]])], - [AC_MSG_RESULT(yes) - BOUT_HAS_PRETTY_FUNCTION=yes], - [AC_MSG_RESULT(no) - BOUT_HAS_PRETTY_FUNCTION=no]) - AC_LANG_POP([C++]) -]) - -dnl First argument is lower case module name -dnl Second argument is test program includes -dnl Third argument is test program main body -AC_DEFUN([BOUT_FIND_SUNDIALS_MODULE],[ - - dnl Slightly complicated as we have to deal with shell indirection - AS_VAR_COPY([with_module], [with_$1]) - module_upper=m4_toupper($1) - - AC_MSG_NOTICE([Searching for SUNDIALS $module_upper library]) - AS_IF([test "$with_module" = "yes"], [ - # No path specified. Try using sundials-config - AC_PATH_PROG([sundials_config], [sundials-config], [no], [$with_sundials$PATH_SEPARATOR$PATH]) - AS_IF([test "x$sundials_config" != xno], [ - AC_MSG_WARN( - [Found sundials-config, this means your version of SUNDIALS is < 2.6, and probably won't work]) - sundials_module_includes=`$sundials_config -m $1 -t p -l c -s cppflags` - sundials_module_libs=`$sundials_config -m $1 -t p -l c -s libs` - ], [ - AC_MSG_WARN([No sundials-config available, no path given, will try compiling with $module_upper anyway]) - sundials_module_includes="" - # Need to link to libsundials_ida, libsundials_cvode or libsundials_arkode - sundials_module_libs="-lsundials_$1 -lsundials_nvecparallel $SUNDIALS_EXTRA_LIBS" - ]) - AC_LANG_PUSH([C++]) - AC_MSG_CHECKING([if we can compile with SUNDIALS $module_upper]) - save_LIBS=$LIBS - save_CXXFLAGS=$CXXFLAGS - LIBS="$save_LIBS $sundials_module_libs" - CXXFLAGS="$save_CXXFLAGS $sundials_module_includes" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([ -$2 - ], [$3])], - [sundials_config_worked=yes], - [sundials_config_worked=no]) - AC_MSG_RESULT([$sundials_config_worked]) - AS_IF([test $sundials_config_worked = yes], [ - AC_MSG_NOTICE([Using SUNDIALS $module_upper solver]) - ], [ - AC_MSG_FAILURE([Could not compile SUNDIALS $module_upper program, check your SUNDIALS version]) - ]) - LIBS=$save_LIBS - CXXFLAGS="$save_CXXFLAGS" - AC_LANG_POP([C++]) - ], [ - # Specified with path - AC_MSG_NOTICE([Checking for $module_upper header files]) - - # Check whether user supplied path to $module_upper install dir... - AC_CHECK_FILES([$with_module/include/$1/$1.h - $with_module/include/$1/$1_spgmr.h - $with_module/include/$1/$1_bbdpre.h - $with_module/include/nvector/nvector_parallel.h - $with_module/include/sundials/sundials_types.h], - [sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/include], - [sundials_module_includes_found=no]) - AS_IF([test $sundials_module_includes_found = no], [ - # ...or path to $module_upper lib dir - AC_CHECK_FILES([$with_module/../include/$1/$1.h - $with_module/../include/$1/$1_spgmr.h - $with_module/../include/$1/$1_bbdpre.h - $with_module/../include/nvector/nvector_parallel.h - $with_module/../include/sundials/sundials_types.h], - [sundials_module_includes_found=yes - sundials_module_includes_path=$with_module/../include], - [sundials_module_includes_found=no]) - ]) - - AS_IF([test $sundials_module_includes_found = no], - [AC_MSG_FAILURE([Missing one or more $module_upper headers])]) - - AC_MSG_NOTICE([Found $module_upper include path: $sundials_module_includes_path]) - - # We've now got the include directory and can specify what libraries we need - sundials_module_includes="-I$sundials_module_includes_path" - sundials_module_libs="-lsundials_$1 -lsundials_nvecparallel $SUNDIALS_EXTRA_LIBS" - - # Try compiling something simple with a few different common paths - save_LIBS=$LIBS - save_LDFLAGS=$LDFLAGS - save_CPPFLAGS=$CPPFLAGS - AC_LANG_PUSH([C++]) - for sundials_module_lib_path in "$with_module" "$with_module/lib" "$with_module/lib64" - do - AC_MSG_CHECKING([if SUNDIALS $module_upper library path is $sundials_module_lib_path]) - LIBS="$save_LIBS $sundials_module_libs" - LDFLAGS="$save_LDFLAGS -L$sundials_module_lib_path" - CPPFLAGS="$save_CPPFLAGS $sundials_module_includes" - AC_LINK_IFELSE( - [AC_LANG_PROGRAM([ -$2 - ], [$3])], - [sundials_module_lib_path_found=yes], - [sundials_module_lib_path_found=no]) - AC_MSG_RESULT([$sundials_module_lib_path_found]) - AS_IF([test "x$sundials_module_lib_path_found" = "xyes"], [break]) - LIBS=$save_LIBS - LDFLAGS=$save_LDFLAGS - CPPFLAGS="$save_CPPFLAGS" - done - AC_LANG_POP([C++]) - - SUNDIALS_MODULE_LDFLAGS="-L$sundials_module_lib_path" - ]) - - AS_IF([test "x$sundials_module_lib_path_found" = "xno"], - [AC_MSG_FAILURE([Cannot compile $module_upper program])]) - - # Compile in the $module_upper solver - AC_MSG_NOTICE([=> $module_upper solver enabled]) - EXTRA_LIBS="$EXTRA_LIBS $SUNDIALS_MODULE_LDFLAGS $sundials_module_libs" - EXTRA_INCS="$EXTRA_INCS $sundials_module_includes" - - dnl The following is slightly complicated, but basically we use - dnl AS_TR_SH to construct a shell variable from the variable - dnl module_upper. This causes some shell indirection though, so we - dnl then use AS_VAR_SET to actually assign the value we want to it - AS_VAR_SET([AS_TR_SH([BOUT_HAS_$module_upper])], [yes]) - AS_VAR_SET([AS_TR_SH([${module_upper}LIBS])], ["$SUNDIALS_MODULE_LDFLAGS $sundials_module_libs"]) - AS_VAR_SET([AS_TR_SH([${module_upper}INCS])], ["$sundials_module_includes"]) -]) - - -# BOUT_DEFINE_SUBST(NAME, VALUE, DESCRIPTION) -# Create an output variable and also define it for headers -# Taken from https://stackoverflow.com/a/8735145/2043465 -# ----------------------------------------- -AC_DEFUN([BOUT_DEFINE_SUBST], [ -AS_IF([test "x$$1" = "xyes"], -[AC_DEFINE([$1], [1], [$2])], -[AC_DEFINE([$1], [0], [$2])]) -AC_SUBST([$1]) -]) diff --git a/make.config.in b/make.config.in deleted file mode 100644 index b7a4bf69f4..0000000000 --- a/make.config.in +++ /dev/null @@ -1,441 +0,0 @@ -# configuration file for BOUT++ -# September 2008: Converted to use autoconf. Can be manually edited -# for the (very) rare occasions when autoconf fails - -# extra compilation flags: -# -DCHECK=lvl Enables a host of additional checks on each operation -# such as uninitialised data if lvl is > 0. -DCHECK=3 -# enables all tests, while -DCHECK=0 disables them. -# Helps when debugging -# -DTRACK Keeps track of variable names. -# Enables more useful error messages -# for SSE2: -msse2 -mfpmath=sse -# -# This must also specify one or more file formats -# -DPDBF PDB format (need to include pdb_format.cxx) -# -DNCDF NetCDF format (nc_format.cxx) - -# PETSc config variables need to be first, else they may clobber other -# options (e.g. CXX, CXXFLAGS) -PETSC_DIR ?= @PETSC_DIR@ -PETSC_ARCH ?= @PETSC_ARCH@ -@PETSC_MAKE_INCLUDE@ -SLEPC_DIR ?= @SLEPC_DIR@ -SLEPC_ARCH ?= @SLEPC_ARCH@ -@SLEPC_MAKE_INCLUDE@ - -# These lines can be replaced in "make install" to point to install directories -# They are used in the CXXFLAGS variable below rather than hard-coding the directories -BOUT_INCLUDE_PATH=$(BOUT_TOP)/include -BOUT_LIB_PATH=$(BOUT_TOP)/lib -BOUT_CONFIG_FILE=$(BOUT_TOP)/make.config - -prefix = @prefix@ -exec_prefix = @exec_prefix@ -datarootdir = @datarootdir@ - -# This path to the locale (.mo) files is hard-wired into bout++.cxx at compile time -BOUT_LOCALE_PATH=@localedir@ - -# Created this variable so that a user won't overwrite the CXXFLAGS variable -# on the command line, just add to this one -BOUT_FLAGS = $(CXXFLAGS) @CXXFLAGS@ @OPENMP_CXXFLAGS@ @COVERAGE_FLAGS@ -#Use := here to force a "static" evaluation of the current state of BOUT_FLAGS to -#avoid infinite recursion that would arise if BOUT_FLAGS appeared on both sides of = -BOUT_FLAGS := $(BOUT_FLAGS) -DBOUT_FLAGS_STRING="$(BOUT_FLAGS)" - -# Specify the MPI C++ compiler in CXX - -CXX = @CXX@ -CC = $(CXX) - -AR = ar -ARFLAGS = @ARFLAGS@ -RANLIB = @RANLIB@ -MKDIR = @MKDIR_P@ - -#################################################################### -# Do not need to alter anything below -#################################################################### - -LD = $(CXX) -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -CPPFLAGS = @CPPFLAGS@ - -#################################################################### -# Extra (optional) source files, includes and libs -# NOTE: EXTRA_SRC must include a solver (solver.cxx or ida_solver.cxx) -# and a file format (nc_format.cxx or pdb_format.cxx) -#################################################################### - -EXTRA_INCS = $(CPPFLAGS) @EXTRA_INCS@ -EXTRA_LIBS = $(LIBS) @EXTRA_LIBS@ @OPENMP_CXXFLAGS@ - -PRECON_SOURCE = @PRECON_SOURCE@ - -BOUT_VERSION = @PACKAGE_VERSION@ - -#################################################################### -# These are used for compiling physics modules using BOUT++ library -#################################################################### - -# Files that are needed by configure and should be dependencies for 'all' - -OBJ = $(SOURCEC:%.cxx=%.o) -ifndef RELEASED -# If this is part of an packaged and installed installation, the user cannot -# write these files, so they shouldn't be changed. Thus only set this, in -# the non installed case. -LIB_A = $(BOUT_LIB_PATH)/libbout++.a -LIB_SO = $(BOUT_LIB_PATH)/libbout++.so -LIB = @LIB_TO_BUILD@ -endif - -MPARK_VARIANT_INCLUDE_PATH=@MPARK_VARIANT_INCLUDE_PATH@ -FMT_INCLUDE_PATH=@FMT_INCLUDE_PATH@ -BOUT_INCLUDE = -I$(BOUT_INCLUDE_PATH) $(CXXINCLUDE) $(EXTRA_INCS) @MPARK_INCLUDE@ -I$(FMT_INCLUDE_PATH) -BOUT_LIBS = -lm -L$(BOUT_LIB_PATH) -lbout++ $(EXTRA_LIBS) - -CHANGED = $(shell find -f $(BOUT_TOP)/include $(BOUT_TOP)/src -type f \( -name \*.cxx -or -name \*.h \) -newer $(LIB) -print 2> /dev/null) - -# This will set a default if no TARGET is provided -TARGET ?= $(SOURCEC:%.cxx=%) - -#################################################################### -# Definining stuff for recursive make -#################################################################### - -# Phony targets since they are directory names -.PHONY: $(DIRS) lib install libfast runtest manual sphinx doxygen - -ifneq ("$(TARGET)","libfast") -all: $(BOUT_CONFIG_FILE) $(DIRS) $(TARGET) -else -all: $(BOUT_TOP)/config.status $(BOUT_CONFIG_FILE) $(DIRS) -endif -libfast: $(BOUT_CONFIG_FILE) $(DIRS) - -#################################################################### -# Recursively run make through subdirs -#################################################################### - -ifeq ("$(TARGET)" , "lib") -$(DIRS): -# make $@ slowly using the old method where parallel builds can cause -# race conditions that - @$(MAKE) -s --no-print-directory TARGET=lib -C $@ all -else -ifeq ("$(TARGET)","libfast") -$(DIRS): -# make $@ using the libfast method, where all .o files -# are only created in the end - @$(MAKE) -s --no-print-directory TARGET=$(TARGET) -C $@ $(TARGET) -else -MODULE_DIR?=$(shell pwd) -$(DIRS): -# MODULE_DIR: pass the module directory, where the libraries should be -# created. -# SUB_NAME is used for creating a library with the expected name. -# first a potential trailing slash is removed, and after that the -# directory name is extracted. This allows to e.g. specify a directory -# as fuu/bar/ and still get an archive named bar.a - @$(MAKE) -s --no-print-directory MODULE_DIR=$(MODULE_DIR) SUB_NAME=$(shell basename $@) TARGET=sub -C $@ -endif -endif - -# Create 'lib' and 'include' incase they don't exist -$(BOUT_TOP)/include $(BOUT_TOP)/lib: - $(MKDIR) $@ - -#################################################################### -# Install header files and libraries -#################################################################### - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = ${INSTALL} -INSTALL_DATA = ${INSTALL} -m 644 - -INSTALL_INCLUDE_PATH = $(DESTDIR)@includedir@/bout++/ - -# A list of relative paths e.g. "fr/LC_MESSAGES/libbout.mo zh_CN/LC_MESSAGES/libbout.mo" -MO_FILES = $(shell cd locale; ls */LC_MESSAGES/libbout.mo) - -install: libfast - $(PRE_INSTALL) # Pre-install commands follow. - - $(NORMAL_INSTALL) # Normal commands follow. - $(MKDIR) $(INSTALL_INCLUDE_PATH)/{,pvode,bout/sys,bout/invert} - $(MKDIR) $(DESTDIR)/{@libdir@,@bindir@,@datadir@/bout++/idllib} - $(MKDIR) $(DESTDIR)/@datadir@/bout++/pylib/{boutdata,boututils} - $(INSTALL_DATA) include/*.hxx $(INSTALL_INCLUDE_PATH) -ifeq ("@OWN_MPARK@", "yes") - $(MKDIR) $(INSTALL_INCLUDE_PATH)/mpark - $(INSTALL_DATA) $(MPARK_VARIANT_INCLUDE_PATH)/mpark/*.hpp $(INSTALL_INCLUDE_PATH)/mpark -endif - $(INSTALL_DATA) $(FMT_INCLUDE_PATH)/fmt/*.h $(INSTALL_INCLUDE_PATH)/fmt - $(INSTALL_DATA) include/pvode/*.h $(INSTALL_INCLUDE_PATH)/pvode/ - $(INSTALL_DATA) include/bout/*.hxx $(INSTALL_INCLUDE_PATH)/bout/ - $(INSTALL_DATA) include/bout/sys/*.hxx $(INSTALL_INCLUDE_PATH)/bout/sys/ - $(INSTALL_DATA) include/bout/invert/*.hxx $(INSTALL_INCLUDE_PATH)/bout/invert/ - $(INSTALL_DATA) lib/libbout++.a $(DESTDIR)@libdir@ - $(INSTALL_DATA) lib/libpvode.a $(DESTDIR)@libdir@ - $(INSTALL_DATA) lib/libpvpre.a $(DESTDIR)@libdir@ -ifneq ("@SHARED_EXTRA@x", "x") - $(INSTALL_PROGRAM) lib/libbout++.so.$(SONAME) $(DESTDIR)@libdir@ - $(INSTALL_PROGRAM) lib/libpvode.so.* $(DESTDIR)@libdir@ - $(INSTALL_PROGRAM) lib/libpvpre.so.* $(DESTDIR)@libdir@ - rm -f $(DESTDIR)@libdir@/lib{bout++,pvode,pvpre}.so - ln -s libbout++.so.$(SONAME) $(DESTDIR)@libdir@/libbout++.so - ln -s libpvode.so.1.0.0 $(DESTDIR)@libdir@/libpvode.so - ln -s libpvpre.so.1.0.0 $(DESTDIR)@libdir@/libpvpre.so -endif - $(INSTALL_PROGRAM) bin/bout-config $(DESTDIR)@bindir@ - $(INSTALL_PROGRAM) bin/bout-log-color $(DESTDIR)@bindir@ - $(INSTALL_DATA) tools/idllib/*.pro $(DESTDIR)@datadir@/bout++/idllib/ - $(INSTALL_DATA) tools/idllib/README $(DESTDIR)@datadir@/bout++/idllib/ - $(INSTALL_DATA) tools/pylib/boutdata/*.py $(DESTDIR)@datadir@/bout++/pylib/boutdata/ - $(INSTALL_DATA) tools/pylib/boututils/*.py $(DESTDIR)@datadir@/bout++/pylib/boututils/ - $(INSTALL_DATA) make.config $(INSTALL_INCLUDE_PATH) - for mo in $(MO_FILES); do $(MKDIR) $(DESTDIR)@localedir@/`dirname $$mo`; $(INSTALL_DATA) locale/$$mo $(DESTDIR)@localedir@/$$mo; done - $(POST_INSTALL) # Post-install commands follow. - - @# Modify paths in the bout-config script - sed -i "s|^BOUT_INCLUDE_PATH=.*|BOUT_INCLUDE_PATH=@includedir@/bout++|" $(DESTDIR)@bindir@/bout-config - sed -i "s|^BOUT_LIB_PATH=.*|BOUT_LIB_PATH=@libdir@|" $(DESTDIR)@bindir@/bout-config - sed -i "s|^BOUT_CONFIG_FILE=.*|BOUT_CONFIG_FILE=@includedir@/bout++/make.config|" $(DESTDIR)@bindir@/bout-config - sed -i "s|^idlpath=.*|idlpath=@datadir@/bout++/idllib/|" $(DESTDIR)@bindir@/bout-config - sed -i "s|^pythonpath=.*|pythonpath=@datadir@/bout++/pylib/|" $(DESTDIR)@bindir@/bout-config -ifeq ("@OWN_MPARK@", "yes") - sed -i "s|^MPARK_VARIANT_INCLUDE_PATH=.*|MPARK_VARIANT_INCLUDE_PATH=@includedir@/bout++|" $(DESTDIR)@bindir@/bout-config -endif - sed -i "s|^FMT_INCLUDE_PATH=.*|FMT_INCLUDE_PATH=@includedir@/bout++|" $(DESTDIR)@bindir@/bout-config - - @# Modify paths in the make.config file - sed -i "s|^BOUT_INCLUDE_PATH=.*|BOUT_INCLUDE_PATH=@includedir@/bout++|" $(INSTALL_INCLUDE_PATH)/make.config - sed -i "s|^BOUT_LIB_PATH=.*|BOUT_LIB_PATH=@libdir@|" $(INSTALL_INCLUDE_PATH)/make.config - sed -i "s|^BOUT_CONFIG_FILE=.*|BOUT_CONFIG_FILE=@includedir@/bout++/make.config|" $(INSTALL_INCLUDE_PATH)/make.config -ifeq ("@OWN_MPARK@", "yes") - sed -i "s|^MPARK_VARIANT_INCLUDE_PATH=.*|MPARK_VARIANT_INCLUDE_PATH=@includedir@/bout++|" $(INSTALL_INCLUDE_PATH)/make.config -endif - sed -i "s|^FMT_INCLUDE_PATH=.*|FMT_INCLUDE_PATH=@includedir@/bout++|" $(INSTALL_INCLUDE_PATH)/make.config - -# Set the make.config as released, so the library isn't rebuild. This way the .a file doesn't need to be preserved/installed - sed -i '26 i RELEASED = yes' $(INSTALL_INCLUDE_PATH)/make.config - -uninstall: - $(PRE_UNINSTALL) # Pre-uninstall commands follow. - - $(NORMAL_UNINSTALL) # Normal commands follow. - $(RM) -r $(DESTDIR)@datadir@/bout++/pylib/boututils/ - $(RM) -r $(DESTDIR)@datadir@/bout++/pylib/boutdata/ - $(RM) -r $(DESTDIR)@datadir@/bout++/idllib/ - $(RM) $(DESTDIR)@bindir@/bout-config - $(RM) $(DESTDIR)@bindir@/bout-log-color - $(RM) $(DESTDIR)@libdir@/libbout++.a - $(RM) $(DESTDIR)@libdir@/libpvode.a - $(RM) $(DESTDIR)@libdir@/libpvpre.a - $(RM) -r $(DESTDIR)@includedir@/bout++/ - $(RM) $(DESTDIR)@localedir@/*/LC_MESSAGES/libbout.mo - - $(POST_UNINSTALL) # Post-uninstall commands follow. - -#################################################################### -# Builds the library with $(OBJ) which is defined from the SOURCEC variable -#################################################################### - -# Rules for downloading submodules --include $(BOUT_TOP)/makefile.submodules - -ifeq ("$(TARGET)", "libfast") -libfast: makefile $(BOUT_CONFIG_FILE) $(BOUT_TOP)/include $(OBJ) $(DIRS) -endif - -ifeq ("$(TARGET)", "lib") -lib: makefile $(BOUT_CONFIG_FILE) $(BOUT_TOP)/include $(BOUT_TOP)/lib $(OBJ) -ifneq ("$(OBJ)foo", "foo") - @echo " Adding $(OBJ) to libbout++.a" - @$(AR) $(ARFLAGS) $(LIB_A) $(OBJ) - @$(RANLIB) $(LIB) -endif -endif - - -ifeq ("$(TARGET)", "sub") -LIB=$(MODULE_DIR)/$(SUB_NAME).a -sub:$(LIB) - -$(LIB): makefile $(BOUT_CONFIG_FILE) $(BOUT_TOP)/include $(BOUT_TOP)/lib $(OBJ) -ifneq ("$(OBJ)foo", "foo") - @echo " Adding $(OBJ) to $(LIB)" - @LIBT=$(LIB).$$$$.a && \ - $(AR) $(ARFLAGS) $${LIBT} $(OBJ) && \ - $(RANLIB) $${LIBT} && \ - mv $${LIBT} $(LIB) -endif -endif - -runtest: - ./runtest - - -ifneq ("$(TARGET)", "sub") -ifneq ("$(TARGET)", "libfast") -ifneq ("$(TARGET)", "lib") -ifneq ("$(TARGET)", "runtest") - -#################################################################### -# Make libbout++.a if it doesn't exist with the checklib target -#################################################################### -libbout++.a: - @echo "Rebuilding out-of-date bout++ library" - @$(MAKE) --no-print-directory -C $(BOUT_TOP) - -#################################################################### -# Make the target (e.g. gas_compress) -#################################################################### -# first we remove a trailing slash, if present. Note that currently we -# dont support several trailing slashes, as in fuu/bar/// -DIRS_=$(DIRS:%/=%) -# then we extract the directory name, in case it is a longer path -# We are not in a recipe, so # needs to be escaped -# $$ is an escaped $ -DIRS__=$(shell for d in $(DIRS_) ; do basename $$d;done) -# now we can generate a list of libraries -SUB_LIBS=$(DIRS__:%=%.a) -$(SUB_LIBS):$(DIRS__) - -$(SOURCEC): checklib -$(SOURCEC:%.cxx=%.o): $(LIB) -$(TARGET): | $(DIRS) -$(TARGET): makefile $(BOUT_CONFIG_FILE) $(OBJ) $(SUB_LIBS) - @echo " Linking" $(TARGET) - @$(LD) -o $(TARGET) $(OBJ) $(SUB_LIBS) $(BOUT_LIBS) $(LDFLAGS) - -checklib: -ifneq ("$(CHANGED)foo", "foo") - @echo "Rebuilding out-of-date bout++ library" - @$(MAKE) --no-print-directory -C $(BOUT_TOP) -endif - -endif -endif -endif -endif - -# Ignore missing requirement files --include .*.mk - -# If it is a libfast target, track changes to rebuild library if needed -# -# Further track dependencies using gcc's -M feature: -# -MF write the generated dependency rule to a file -# -MG assume missing headers will be generated and don't stop with an error -# -MM generate dependency rule for prerequisite, skipping system headers -# -MP add phony target for each header to prevent errors when header is missing -# -MT add a target to the generated dependency -# Ignore failure, in case some compiler does not support this -%.o: $(BOUT_CONFIG_FILE) %.cxx - @echo " Compiling " $(@:.o=.cxx) - @$(CXX) $(BOUT_INCLUDE) $(BOUT_FLAGS) -c $(@:.o=.cxx) -o $@ -ifeq ("$(TARGET)","libfast") - @test "$@" = "bout++-time.o" || touch $(BOUT_TOP)/lib/.last.o.file -endif - -#################################################################### -# Clean target. Pretty self explanatory. -# NOTE: See that double colon (::) below? That's signifies a rule that can be added to later -# See: -# http://owen.sj.ca.us/~rk/howto/slides/make/slides/makecolon.html -#################################################################### - -clean:: - -@$(RM) -rf $(OBJ) $(DEPS) $(TARGET) - @for pp in $(DIRS) $(DIRS_CLEAN); do echo " " cleaning $$pp; $(MAKE) --no-print-directory -C $$pp clean; done - @$(RM) -f $(SUB_LIBS) - -@$(RM) .*.mk - @test -f make.config && ( find src | grep '\.o$$' && echo "WARNING: Some object files remain - which might cause issues. Clean with $(MAKE) clean-remove-object-files" ) || exit 0 - -clean-remove-object-files: - find src|grep '\.o$$' | xargs rm - - -distclean:: clean clean-tests - @echo include cleaned -# Removing the externalpackage installation. When we have more packages, need a better way - @$(RM) -rf $(BOUT_TOP)/include/pvode - @echo lib cleaned - @$(RM) -rf $(BOUT_TOP)/lib/* - -@$(RM) $(BOUT_TOP)/externalpackages/PVODE/lib/*.a - -@$(RM) $(BOUT_TOP)/externalpackages/PVODE/source/obj/*.o - -@$(RM) $(BOUT_TOP)/externalpackages/PVODE/precon/obj/*.o - -@$(RM) -rf $(BOUT_TOP)/autom4te.cache make.config - @echo externalpackages cleaned - @touch $(BOUT_TOP)/configure - @echo autom4te.cache cleaned - -@$(RM) $(BOUT_TOP)/include/bout/version.hxx - -@$(RM) $(BOUT_TOP)/include/bout/revision.hxx - -@$(RM) $(BOUT_TOP)/include/bout/build_defines.hxx - @echo generated version headers cleaned - -@$(RM) $(BOUT_TOP)/tools/pylib/boutconfig/__init__.py - @echo generated Python boutconfig module cleaned - -clean-tests: clean-unit-tests clean-integrated-tests clean-mms-tests - -clean-unit-tests: - @echo " tests/unit cleaned" - @$(MAKE) --no-print-directory -C tests/unit clean - -clean-integrated-tests: - @echo " tests/integrated cleaned" - @$(MAKE) --no-print-directory -C tests/integrated clean - -clean-mms-tests: - @echo " tests/MMS cleaned" - @$(MAKE) --no-print-directory -C tests/MMS clean - -#################################################################### -# Documentation -#################################################################### - -MANUAL_DIR=$(BOUT_TOP)/manual - -doxygen: - $(MAKE) -C $(MANUAL_DIR) doxygen - -breathe-autogen: - $(MAKE) -C $(MANUAL_DIR) breathe_autogen - -sphinx-docs-html: - $(MAKE) -C $(MANUAL_DIR) sphinx-html - -sphinx-docs-latex: - $(MAKE) -C $(MANUAL_DIR) sphinx-pdf - -manual: - $(MAKE) -C $(MANUAL_DIR) - -manual-html: - $(MAKE) -C $(MANUAL_DIR) html - -manual-pdf: - $(MAKE) -C $(MANUAL_DIR) pdf - -python: libfast - $(MAKE) -C tools/pylib python3 - -python2: libfast - $(MAKE) -C tools/pylib python2 - -python-all:python python2 - -###################################################################### -# Code coverage -###################################################################### - -GCOV = @GCOV@ -LCOV = @LCOV@ -GENHTML = @GENHTML@ -abs_builddir = @abs_builddir@ - -@CODE_COVERAGE_RULES@ diff --git a/makefile b/makefile deleted file mode 100644 index 10949da529..0000000000 --- a/makefile +++ /dev/null @@ -1,117 +0,0 @@ -BOUT_TOP = $(PWD) - -DIRS = src - -DIRS_CLEAN = tests/integrated tests/unit tests/MMS - -TARGET ?= libfast - -include make.config - -# For compatibility ignore shared -shared: libfast - -###################################################################### -# Tests -###################################################################### - -check-unit-tests: libfast - @export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH}; $(MAKE) --no-print-directory -C tests/unit check - -check-mms-tests: libfast - +@cd tests/MMS; export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH} ; \ - PYTHONPATH=${PWD}/tools/pylib/:${PYTHONPATH} \ - OMPI_MCA_rmaps_base_oversubscribe=yes ./test_suite_make - +@cd tests/MMS; export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH} ; \ - PYTHONPATH=${PWD}/tools/pylib/:${PYTHONPATH} \ - OMPI_MCA_rmaps_base_oversubscribe=yes ./test_suite - -check-mms-tests-all: libfast - +@cd tests/MMS; export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH} ; \ - PYTHONPATH=${PWD}/tools/pylib/:${PYTHONPATH} \ - OMPI_MCA_rmaps_base_oversubscribe=yes ./test_suite_make --all - +@cd tests/MMS; export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH} ; \ - PYTHONPATH=${PWD}/tools/pylib/:${PYTHONPATH} \ - OMPI_MCA_rmaps_base_oversubscribe=yes ./test_suite --all - -check-integrated-tests: libfast - +@cd tests/integrated; export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH} ; \ - PYTHONPATH=${PWD}/tools/pylib/:${PYTHONPATH} \ - OMPI_MCA_rmaps_base_oversubscribe=yes ./test_suite_make - +@cd tests/integrated; export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH} ; \ - PYTHONPATH=${PWD}/tools/pylib/:${PYTHONPATH} \ - OMPI_MCA_rmaps_base_oversubscribe=yes ./test_suite - -check-integrated-tests-all: libfast - +@cd tests/integrated; export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH} ; \ - PYTHONPATH=${PWD}/tools/pylib/:${PYTHONPATH} \ - OMPI_MCA_rmaps_base_oversubscribe=yes ./test_suite_make --all - +@cd tests/integrated; export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH} ; \ - PYTHONPATH=${PWD}/tools/pylib/:${PYTHONPATH} \ - OMPI_MCA_rmaps_base_oversubscribe=yes ./test_suite --all - - -check: build-check - +@cd tests; export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH} ; \ - PYTHONPATH=${PWD}/tools/pylib/:${PYTHONPATH} \ - OMPI_MCA_rmaps_base_oversubscribe=yes ./test_suite -check-all: build-check-all - +@cd tests; export LD_LIBRARY_PATH=${PWD}/lib:${LD_LIBRARY_PATH} ; \ - PYTHONPATH=${PWD}/tools/pylib/:${PYTHONPATH} \ - OMPI_MCA_rmaps_base_oversubscribe=yes ./test_suite --all - -build-check-unit-tests: libfast - @$(MAKE) --no-print-directory -C tests/unit - -build-check-mms-tests: libfast - $(MAKE) --no-print-directory -C tests/MMS -build-check-mms-tests-all: libfast - $(MAKE) --no-print-directory -C tests/MMS all-all - -build-check-integrated-tests: libfast - $(MAKE) --no-print-directory -C tests/integrated -build-check-integrated-tests-all: libfast - $(MAKE) --no-print-directory -C tests/integrated all-all - - -build-check: build-check-integrated-tests build-check-mms-tests build-check-unit-tests -build-check-all: build-check-integrated-tests-all build-check-mms-tests-all build-check-unit-tests - -# Build the .mo files needed for Natural Language Support (gettext) -.PHONY: locale -locale: - $(MAKE) -C locale - -###################################################################### -# Releases -###################################################################### - -.PHONY: dist changelog - -# Makes the tarball BOUT++-v.tar.gz -dist: - @bin/bout-archive-helper.sh v$(BOUT_VERSION) - -CHANGELOG_ERR_MESSAGE := "Run like: make changelog TOKEN= LAST_VERSION=vX.Y.Z RELEASE_BRANCH=master|next" - -# Updates CHANGELOG.md, needs some arguments: -# -# make changelog TOKEN= LAST_VERSION=vX.Y.Z RELEASE_BRANCH=master|next -# -# Note: You should probably only run this if you are a maintainer (and -# also know what you're doing)! -changelog: -ifndef TOKEN - $(error $(CHANGELOG_ERR_MESSAGE)) -endif -ifndef LAST_VERSION - $(error $(CHANGELOG_ERR_MESSAGE)) -endif -ifndef RELEASE_BRANCH - $(error $(CHANGELOG_ERR_MESSAGE)) -endif - github_changelog_generator -t $(TOKEN) --since-tag \ - $(LAST_VERSION) --no-issues --max-issues 700 \ - --base CHANGELOG.md --future-release v$(BOUT_VERSION) \ - --release-branch $(RELEASE_BRANCH) \ - --user boutproject --project BOUT-dev diff --git a/makefile.submodules b/makefile.submodules deleted file mode 100644 index d590e0e72e..0000000000 --- a/makefile.submodules +++ /dev/null @@ -1,15 +0,0 @@ -# This is in a separate file so that we can download the submodules at -# configure-time, as well as exposing a nice target if things go wrong -# afterwards (for example, after changing branches) - -submodules: sub_all - -mpark_submodule: - @echo "Downloading mpark.variant" - git submodule update --init --recursive ./externalpackages/mpark.variant - -sub_all: - @for d in $$(ls externalpackages | grep -v PVODE) ; do echo "Downloading $$d" ; git submodule update --init --recursive ./externalpackages/$$d ; done - -python_submodules: - @for d in boututils boutdata ; do echo "Downloading $$d" ; git submodule update --init --recursive ./externalpackages/$$d ; done \ No newline at end of file diff --git a/manual/sphinx/conf.py b/manual/sphinx/conf.py index 29c0985841..d27e8ab1fd 100755 --- a/manual/sphinx/conf.py +++ b/manual/sphinx/conf.py @@ -88,7 +88,7 @@ def __getattr__(cls, name): + " -DBOUT_UPDATE_GIT_SUBMODULE=OFF" + " -DBOUT_TESTS=OFF" + " -DBOUT_ALLOW_INSOURCE_BUILD=ON" - + f" -DPython_ROOT_DIR={pydir}" + + f" -DPython3_ROOT_DIR={pydir}" + f" -Dmpark_variant_DIR={pwd}/externalpackages/mpark.variant/" + f" -Dfmt_DIR={pwd}/externalpackages/fmt/" ) diff --git a/manual/sphinx/developer_docs/data_types.rst b/manual/sphinx/developer_docs/data_types.rst index 2e303381f9..fa8e9e6ea6 100644 --- a/manual/sphinx/developer_docs/data_types.rst +++ b/manual/sphinx/developer_docs/data_types.rst @@ -300,7 +300,7 @@ verion of the macro:: For loops inside parallel regions, there is ``BOUT_FOR_INNER``:: Field3D f(0.0); - BOUT_OMP(parallel) { + BOUT_OMP_PERF(parallel) { BOUT_FOR_INNER(i, f.getMesh()->getRegion3D("RGN_ALL")) { f[i] = a[i] + b[i]; } @@ -357,7 +357,7 @@ Tuning BOUT_FOR loops The ``BOUT_FOR`` macros use two nested loops: The outer loop is OpenMP parallelised, and iterates over contiguous blocks:: - BOUT_OMP(parallel for schedule(guided)) + BOUT_OMP_PERF(parallel for schedule(guided)) for (auto block = region.getBlocks().cbegin(); block < region.getBlocks().cend(); ++block) diff --git a/manual/sphinx/index.rst b/manual/sphinx/index.rst index 46728c7119..9f661ca187 100644 --- a/manual/sphinx/index.rst +++ b/manual/sphinx/index.rst @@ -42,6 +42,7 @@ The documentation is divided into the following sections: user_docs/boundary_options user_docs/testing user_docs/gpu_support + user_docs/adios2 .. toctree:: :maxdepth: 2 diff --git a/manual/sphinx/user_docs/adios2.rst b/manual/sphinx/user_docs/adios2.rst new file mode 100644 index 0000000000..d8e0135c0d --- /dev/null +++ b/manual/sphinx/user_docs/adios2.rst @@ -0,0 +1,45 @@ +.. _sec-adios2: + +ADIOS2 support +============== + +This section summarises the use of `ADIOS2 `_ in BOUT++. + +Installation +------------ + +The easiest way to configure BOUT++ with ADIOS2 is to tell CMake to download and build it +with this flag:: + + -DBOUT_DOWNLOAD_ADIOS2=ON + +The ``master`` branch will be downloaded from `Github `_, +configured and built with BOUT++. + +Alternatively, if ADIOS2 is already installed then the following flags can be used:: + + -DBOUT_USE_ADIOS2=ON -DADIOS2_ROOT=/path/to/adios2 + +Output files +------------ + +The output (dump) files are controlled with the root ``output`` options. +By default the output format is NetCDF, so to use ADIOS2 instead set +the output type in BOUT.inp:: + + [output] + type = adios + +or on the BOUT++ command line set ``output:type=adios``. The default +prefix is "BOUT.dmp" so the ADIOS file will be called "BOUT.dmp.bp". To change this, +set the ``output:prefix`` option. + +Restart files +------------- + +The restart files are contolled with the root ``restart_files`` options, +so to read and write restarts from an ADIOS dataset, put in BOUT.inp:: + + [restart_files] + type = adios + diff --git a/manual/sphinx/user_docs/advanced_install.rst b/manual/sphinx/user_docs/advanced_install.rst index b2b6b49c80..048a26a6e3 100644 --- a/manual/sphinx/user_docs/advanced_install.rst +++ b/manual/sphinx/user_docs/advanced_install.rst @@ -47,7 +47,7 @@ source directory: CHECK=no bin/bout-build-deps.sh # or with openmp - not tested, maybe not good to add it to FFTW PETSCFLAGS=--with-openmp=1 FFTWFLAGS="--enable-avx512 --enable-avx-128-fma --with-openmp --enable-threads" bin/bout-build-deps.sh - # and add "--enable-openmp" to ./configure + # and add "-DBOUT_ENABLE_OPENMP=ON" to cmake configure line Infos about options and further info can be obtained by running: @@ -84,29 +84,6 @@ When using CMake on Cray systems like Archer, you need to pass ``-DCMAKE_SYSTEM_NAME=CrayLinuxEnvironment`` so that the Cray compiler wrappers are detected properly. -KNL @ Archer -~~~~~~~~~~~~ - -To use the KNL system, configure BOUT++ as follows: - -.. code-block:: bash - - ./configure MPICXX=CC --host=knl --with-netcdf --with-pnetcdf=no --with-hypre=no CXXFLAGS="-xMIC-AVX512 -D_GLIBCXX_USE_CXX11_ABI=0" - -Atlas -~~~~~ - -.. code-block:: bash - - ./configure --with-netcdf=/usr/local/tools/hdf5-gnu-serial-1.8.1/lib --with-fftw=/usr/local --with-pdb=/usr/gapps/pact/new/lnx-2.5-ib/gnu - -Cab -~~~ - -.. code-block:: bash - - ./configure --with-netcdf=/usr/local/tools/hdf5-gnu-serial-1.8.1/lib --with-fftw=/usr/local/tools/fftw3-3.2 --with-pdb=/usr/gapps/pact/new/lnx-2.5-ib/gnu - Cori ~~~~ @@ -152,52 +129,6 @@ on GPU machines, including Cori. Note that in order to access GPU nodes a request must be made through `NERSC services `_. -Edison -~~~~~~ - -.. code-block:: bash - - module swap PrgEnv-intel PrgEnv-gnu - module load fftw - ./configure MPICC=cc MPICXX=CC --with-netcdf=/global/u2/c/chma/PUBLIC/netcdf_edison/netcdf --with-fftw=/opt/fftw/3.3.0.1/x86_64 - -Hoffman2 -~~~~~~~~ - -.. code-block:: bash - - ./configure --with-netcdf=/u/local/apps/netcdf/current --with-fftw=/u/local/apps/fftw3/current --with-cvode=/u/local/apps/sundials/2.4.0 --with-lapack=/u/local/apps/lapack/current - -Hopper -~~~~~~ - -.. code-block:: bash - - module swap PrgEnv-pgi PrgEnv-gnu - module load netcdf - module swap netcdf netcdf/4.1.3 - module swap gcc gcc/4.6.3 - ./configure MPICC=cc MPICXX=CC --with-fftw=/opt/fftw/3.2.2.1 --with-pdb=/global/homes/u/umansky/PUBLIC/PACT_HOPP2/pact - -Hyperion -~~~~~~~~ - -With the bash shell use - -.. code-block:: bash - - export PETSC_DIR=~farley9/projects/petsc/petsc-3.2-p1 - export PETSC_ARCH=arch-c - ./configure --with-netcdf=/usr/local/tools/netcdf-gnu-4.1 --with-fftw=/usr/local MPICXX=mpiCC EXTRA_LIBS=-lcurl --with-petsc --with-cvode=~farley9/local --with-ida=~farley9/local - -With the tcsh shell use - -.. code-block:: tcsh - - setenv PETSC_DIR ~farley9/projects/petsc/petsc-3.2-p1 - setenv PETSC_ARCH arch-c - ./configure --with-netcdf=/usr/local/tools/netcdf-gnu-4.1 --with-fftw=/usr/local MPICXX=mpiCC EXTRA_LIBS=-lcurl --with-petsc --with-cvode=~farley9/local --with-ida=~farley9/local - MacOS / Apple Darwin ~~~~~~~~~~~~~~~~~~~~ @@ -211,78 +142,15 @@ Compiling with Apple Clang 12, the following configuration has been known to wor where ```` is the path to the build directory -Marconi -~~~~~~~ - -.. code-block:: bash - - module load intel intelmpi fftw lapack - module load szip zlib/1.2.8--gnu--6.1.0 - module load hdf5/1.8.17--intel--pe-xe-2017--binary - module load netcdf-cxx4 - module load python - -To compile for the SKL partition, configure with +MPCDF HPC Systems +~~~~~~~~~~~~~~~~~ +After cloning BOUT-dev and checking out the branch you want (e.g. db-outer), run: .. code-block:: bash - ./configure --enable-checks=0 CPPFLAGS="-Ofast -funroll-loops -xCORE-AVX512 -mtune=skylake" --host skl - -to enable AVX512 vectorization. - -.. note:: As of 20/04/2018, an issue with the netcdf and netcdf-cxx4 - modules means that you will need to remove ``-lnetcdf`` from - ``EXTRA_LIBS`` in ``make.config`` after running - ``./configure`` and before running ``make``. ``-lnetcdf`` - needs also to be removed from ``bin/bout-config`` to allow a - successful build of the python interface. Recreation of - ``boutpp.pyx`` needs to be manually triggered, if - ``boutpp.pyx`` has already been created. - -Marconi with gnu compilers -************************** - -It is also possible to configure on Marconi using gnu compilers, which may give better performance. A set of modules which work as of 4/5/2021 is - -.. code-block:: bash - - module load env-skl - module load profile/advanced - module load intel/pe-xe-2018--binary # note need to keep the 'intel' module loaded in order for shared libraries needed by numpy/scipy to be available - module load gnu/7.3.0 - module load openmpi/4.0.1--gnu--7.3.0 - module load mkl/2017--binary - module load python/3.6.4 - module load szip/2.1--gnu--6.1.0 zlib/1.2.8--gnu--6.1.0 - - bin/bout-build-deps.sh - -And follow the instructions. The result could look something like this with <...> the appropriate path. - -* for an optimized build (some experimentation with optimisation flags would be welcome, please share the results if you do!):: - - ./configure --enable-optimize=3 --enable-checks=no --enable-static --with-netcdf=<...> --with-sundials=<...> --with-fftw=<...> --with-petsc=<...> - -* for a debugging build:: - - ./configure --enable-debug --enable-static --with-netcdf=<...> --with-sundials=<...> --with-fftw=<...> --with-petsc=<...> - -Ubgl -~~~~ - -.. code-block:: bash - - ./configure --with-netcdf CXXFLAGS=-DMPICH_IGNORE_CXX_SEEK CFLAGS=-DMPICH_IGNORE_CXX_SEEK --with-pdb=/usr/gapps/pact/new_s/lnx-2.5-ib --with-netcdf=/usr/local/tools/netcdf/netcdf-4.1_c++ - -Raven / Cobra / Draco -~~~~~~~~~~~~~~~~~~~~~ -.. code-block:: bash - - module purge # or at least onload intel and impi and mkl - module load gcc/10 cmake/3.18 openmpi/4 - # ensure python3 is >= python3.6 - skip if you have a newer python3 loaded - mkdir -p $HOME/bin ; test -e $HOME/bin/python3 || ln -s $(which python3.6) $HOME/bin/python3 - BUILD=/ptmp/$USER/bout-deps bin/bout-build-deps.sh + module purge # or at least onload intel + module load gcc/13 anaconda/3/2021.11 impi/2021.9 hdf5-serial/1.12.2 mkl/2022.0 netcdf-serial/4.8.1 fftw-mpi/3.3.10 + BUILD=/ptmp/$USER/bout-deps NO_HDF5=1 NO_NETCDF=1 NO_FFTW=1 bin/bout-build-deps.sh and follow the instructions for configuring BOUT++. To enable openMP for a production run use: @@ -290,14 +158,21 @@ for a production run use: .. code-block:: bash module load bout-dep - ./configure --with-netcdf=$BOUT_DEP --with-sundials=$BOUT_DEP --with-fftw=$BOUT_DEP --with-petsc=$BOUT_DEP --enable-optimize --enable-openmp + cmake .. -DBOUT_USE_NETCDF=ON -DnetCDFCxx_ROOT=$BOUT_DEP \ + -DBOUT_USE_PETSC=ON -DPETSC_DIR=$BOUT_DEP \ + -DBOUT_USE_FFTW=ON \ + -DBOUT_USE_SUNDIALS=ON -DSUNDIALS_ROOT=$BOUT_DEP \ + -DBOUT_ENABLE_OPENMP=OFF \ + -DCMAKE_BUILD_TYPE=Release File formats ------------ -BOUT++ can currently use the NetCDF-4_ file format, with experimental -support for the parallel flavour. NetCDF is a widely used format and +BOUT++ can currently use the NetCDF-4_ file format and the ADIOS2 library +for high-performance parallel output. + +NetCDF is a widely used format and has many tools for viewing and manipulating files. .. _NetCDF-4: https://www.unidata.ucar.edu/software/netcdf/ @@ -430,9 +305,10 @@ solver. Currently, BOUT++ also supports the SUNDIALS solvers CVODE, IDA and ARKODE which are available from https://computation.llnl.gov/casc/sundials/main.html. -.. note:: BOUT++ currently supports SUNDIALS > 2.6, up to 5.4.0 as of - September 2020. It is advisable to use the highest possible - version +.. note:: BOUT++ currently supports SUNDIALS > 2.6, up to 6.7.0 as of + January 2024. It is advisable to use the highest possible + version. Support for SUNDIALS versions < 4 will be removed + in the next release. The full installation guide is found in the downloaded ``.tar.gz``, but we will provide a step-by-step guide to install it and make it diff --git a/manual/sphinx/user_docs/bout_options.rst b/manual/sphinx/user_docs/bout_options.rst index 5422558ff9..85a8a17d59 100644 --- a/manual/sphinx/user_docs/bout_options.rst +++ b/manual/sphinx/user_docs/bout_options.rst @@ -48,9 +48,10 @@ name in square brackets. Option names can contain almost any character except ’=’ and ’:’, including unicode. If they start with a number or ``.``, contain -arithmetic symbols (``+-*/^``), brackets (``(){}[]``), equality -(``=``), whitespace or comma ``,``, then these will need to be escaped -in expressions. See below for how this is done. +arithmetic/boolean operator symbols (``+-*/^&|!<>``), brackets +(``(){}[]``), equality (``=``), whitespace or comma ``,``, then these +will need to be escaped in expressions. See below for how this is +done. Subsections can also be used, separated by colons ’:’, e.g. @@ -87,6 +88,13 @@ operators, with the usual precedence rules. In addition to ``π``, expressions can use predefined variables ``x``, ``y``, ``z`` and ``t`` to refer to the spatial and time coordinates (for definitions of the values these variables take see :ref:`sec-expressions`). + +.. note:: The variables ``x``, ``y``, ``z`` should only be defined + when reading a 3D field; ``t`` should only be defined when reading + a time-dependent value. Earlier BOUT++ versions (v5.1.0 and earler) + defined all of these to be 0 by default e.g. when reading scalar + inputs. + A number of functions are defined, listed in table :numref:`tab-initexprfunc`. One slightly unusual feature (borrowed from `Julia `_) is that if a number comes before a symbol or an opening bracket (``(``) @@ -109,11 +117,11 @@ The convention is the same as in `Python `_: If brackets are not balanced (closed) then the expression continues on the next line. All expressions are calculated in floating point and then converted to -an integer if needed when read inside BOUT++. The conversion is done by rounding -to the nearest integer, but throws an error if the floating point -value is not within :math:`1e-3` of an integer. This is to minimise -unexpected behaviour. If you want to round any result to an integer, -use the ``round`` function: +an integer (or boolean) if needed when read inside BOUT++. The +conversion is done by rounding to the nearest integer, but throws an +error if the floating point value is not within :math:`1e-3` of an +integer. This is to minimise unexpected behaviour. If you want to +round any result to an integer, use the ``round`` function: .. code-block:: cfg @@ -125,6 +133,43 @@ number, since the type is determined by how it is used. Have a look through the examples to see how the options are used. +Boolean expressions +~~~~~~~~~~~~~~~~~~~ + +Boolean values must be "true", "false", "True", "False", "1" or +"0". All lowercase ("true"/"false") is preferred, but the uppercase +versions are allowed to support Python string conversions. Booleans +can be combined into expressions using binary operators `&` (logical +AND), `|` (logical OR), and unary operator `!` (logical NOT). For +example "true & false" evaluates to `false`; "!false" evaluates to +`true`. Like real values and integers, boolean expressions can refer +to other variables: + +.. code-block:: cfg + + switch = true + other_switch = !switch + +Boolean expressions can be formed by comparing real values using +`>` and `<` comparison operators: + +.. code-block:: cfg + + value = 3.2 + is_true = value > 3 + is_false = value < 2 + +.. note:: + Previous BOUT++ versions (v5.1.0 and earlier) were case + insensitive when reading boolean values, so would read "True" or + "yEs" as `true`, and "False" or "No" as `false`. These earlier + versions did not allow boolean expressions. + +Internally, booleans are evaluated as real values, with `true` being 1 +and `false` being 0. Logical operators (`&`, `|`, `!`) check that +their left and right arguments are either close to 0 or close to 1 +(like integers, "close to" is within 1e-3). + Special symbols in Option names ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -523,6 +568,12 @@ options available are listed in table :numref:`tab-outputopts`. +-------------+----------------------------------------------------+--------------+ | enabled | Writing is enabled | true | +-------------+----------------------------------------------------+--------------+ + | type | File type e.g. "netcdf" or "adios" | "netcdf" | + +-------------+----------------------------------------------------+--------------+ + | prefix | File name prefix | "BOUT.dmp" | + +-------------+----------------------------------------------------+--------------+ + | path | Directory to write the file into | ``datadir`` | + +-------------+----------------------------------------------------+--------------+ | floats | Write floats rather than doubles | false | +-------------+----------------------------------------------------+--------------+ | flush | Flush the file to disk after each write | true | @@ -531,8 +582,6 @@ options available are listed in table :numref:`tab-outputopts`. +-------------+----------------------------------------------------+--------------+ | openclose | Re-open the file for each write, and close after | true | +-------------+----------------------------------------------------+--------------+ - | parallel | Use parallel I/O | false | - +-------------+----------------------------------------------------+--------------+ | @@ -541,20 +590,6 @@ want to exclude I/O from the timings. **floats** can be used to reduce the size of the output files: files are stored as double by default, but setting **floats = true** changes the output to single-precision floats. -To enable parallel I/O for either output or restart files, set - -.. code-block:: cfg - - parallel = true - -in the output or restart section. If you have compiled BOUT++ with a -parallel I/O library such as pnetcdf (see -:ref:`sec-advancedinstall`), then rather than outputting one file per -processor, all processors will output to the same file. For restart -files this is particularly useful, as it means that you can restart a -job with a different number of processors. Note that this feature is -still experimental, and incomplete: output dump files are not yet -supported by the collect routines. Implementation -------------- @@ -833,30 +868,30 @@ This is currently quite rudimentary and needs improving. .. _sec-options-netcdf: -Reading and writing to NetCDF ------------------------------ +Reading and writing to binary formats +------------------------------------- -The `bout::OptionsNetCDF` class provides an interface to read and -write options. Examples are in integrated test +The `bout::OptionsIO` class provides an interface to read and +write options to binary files. Examples are in integrated test ``tests/integrated/test-options-netcdf/`` To write the current `Options` tree (e.g. from ``BOUT.inp``) to a NetCDF file:: - bout::OptionsNetCDF("settings.nc").write(Options::root()); + bout::OptionsIO::create("settings.nc")->write(Options::root()); and to read it in again:: - Options data = bout::OptionsNetCDF("settings.nc").read(); + Options data = bout::OptionsIO::create("settings.nc")->read(); Fields can also be stored and written:: Options fields; fields["f2d"] = Field2D(1.0); fields["f3d"] = Field3D(2.0); - bout::OptionsNetCDF("fields.nc").write(fields); + bout::OptionsIO::create("fields.nc").write(fields); -This should allow the input settings and evolving variables to be +This allows the input settings and evolving variables to be combined into a single tree (see above on joining trees) and written to the output dump or restart files. @@ -865,7 +900,7 @@ an ``Array``, 2D as ``Matrix`` and 3D as ``Tensor``. These can be extracted directly from the ``Options`` tree, or converted to a Field:: - Options fields_in = bout::OptionsNetCDF("fields.nc").read(); + Options fields_in = bout::OptionsIO::create("fields.nc")->read(); Field2D f2d = fields_in["f2d"].as(); Field3D f3d = fields_in["f3d"].as(); @@ -907,7 +942,7 @@ automatically set the ``"time_dimension"`` attribute:: // Or use `assignRepeat` to do it automatically: data["field"].assignRepeat(Field3D(2.0)); - bout::OptionsNetCDF("time.nc").write(data); + bout::OptionsIO::create("time.nc")->write(data); // Update time-dependent values. This can be done without `force` if the time_dimension // attribute is set @@ -915,13 +950,13 @@ automatically set the ``"time_dimension"`` attribute:: data["field"] = Field3D(3.0); // Append data to file - bout::OptionsNetCDF("time.nc", bout::OptionsNetCDF::FileMode::append).write(data); + bout::OptionsIO({{"file", "time.nc"}, {"append", true}})->write(data); -.. note:: By default, `bout::OptionsNetCDF::write` will only write variables +.. note:: By default, `bout::OptionsIO::write` will only write variables with a ``"time_dimension"`` of ``"t"``. You can write variables with a different time dimension by passing it as the second argument: - ``OptionsNetCDF(filename).write(options, "t2")`` for example. + ``OptionsIO::create(filename)->write(options, "t2")`` for example. FFT diff --git a/manual/sphinx/user_docs/installing.rst b/manual/sphinx/user_docs/installing.rst index 7f8c26ffbe..10f5d9b9f1 100644 --- a/manual/sphinx/user_docs/installing.rst +++ b/manual/sphinx/user_docs/installing.rst @@ -124,7 +124,7 @@ Installing dependencies The bare-minimum requirements for compiling and running BOUT++ are: -#. A C++ compiler that supports C++14 +#. A C++ compiler that supports C++17 #. An MPI compiler such as OpenMPI (`www.open-mpi.org/ `__), MPICH ( `https://www.mpich.org/ `__) @@ -140,7 +140,7 @@ FFTW-3, these options will not be available. .. note:: If you use an Intel compiler, you must also make sure that you have - a version of GCC that supports C++14 (GCC 5+). + a version of GCC that supports C++17 (GCC 8+). On supercomputers, or in other environments that use a module system, you may need to load modules for both Intel and GCC. @@ -218,10 +218,10 @@ To get precompiled BOUT++ run:: $ # get the python3 modules - python2 is available as well $ sudo dnf install python3-bout++ -.. _sec-cmake: +.. _sec-config-bout: -CMake ------ +Configuring BOUT++ +------------------ BOUT++ uses the `CMake `_ build system generator. You will need CMake >= 3.17. @@ -373,6 +373,10 @@ For SUNDIALS, use ``-DBOUT_DOWNLOAD_SUNDIALS=ON``. If using ``ccmake`` this opti may not appear initially. This automatically sets ``BOUT_USE_SUNDIALS=ON``, and configures SUNDIALS to use MPI. +For ADIOS2, use ``-DBOUT_DOWNLOAD_ADIOS2=ON``. This will download and +configure `ADIOS2 `_, enabling BOUT++ +to read and write this high-performance parallel file format. + Bundled Dependencies ~~~~~~~~~~~~~~~~~~~~ @@ -391,57 +395,6 @@ The recommended way to use ``googletest`` is to compile it at the same time as your project, therefore there is no option to use an external installation for that. -.. _sec-config-bout: - -./configure ------------ - -.. warning:: - As of BOUT++ 5.0, ``./configure`` is no longer supported and will - be removed in 6.0. Please switch to using CMake to build BOUT++. - -To compile BOUT++, you first need to configure it. -Go into the ``BOUT-dev`` directory and run:: - - $ ./configure - -If this finishes by printing a summary, and paths for IDL, Python, and -Octave, then the libraries are set up and you can skip to the next -section. If you see a message -“``ERROR: FFTW not found. Required by BOUT++``” then make sure -FFTW-3 is installed (See the previous section on :ref:`installing dependencies ` ). - -If FFTW-3 is installed in a non-standard location, you can specify the -directory with the ``–with-fftw=`` option e.g:: - - $ ./configure --with-fftw=$HOME/local - -Configure should now find FFTW, and search for the NetCDF library. If -configure finishes successfully, then skip to the next section, but if -you see a message ``NetCDF support disabled`` then configure couldn’t -find the NetCDF library. This will be followed by a message -``ERROR: At least one file format must be supported``. Check that you have -NetCDF installed (See the previous section on :ref:`installing dependencies ` ). - -Like the FFTW-3 library, if NetCDF is installed in a non-standard location then -you can specify the directory with the ``--with-netcdf=`` option e.g.:: - - $ ./configure --with-fftw=$HOME/local --with-netcdf=$HOME/local - -which should now finish successfully, printing a summary of the -configuration:: - - Configuration summary - PETSc support: no - SLEPc support: no - IDA support: yes - CVODE support: yes - ARKODE support: yes - NetCDF support: yes - Parallel-NetCDF support: no - -If not, see :ref:`sec-advancedinstall` for some things you can try to -resolve common problems. Working with an active ``conda`` environment ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/manual/sphinx/user_docs/laplacian.rst b/manual/sphinx/user_docs/laplacian.rst index e422fa82bd..5365ba14a7 100644 --- a/manual/sphinx/user_docs/laplacian.rst +++ b/manual/sphinx/user_docs/laplacian.rst @@ -536,7 +536,6 @@ Fourth order approximation &+ c_{i-2,j} f_{i-2,j} + c_{i-2,j+1} f_{i-2,j+1} \\ &+ c_{i-2,j+2} f_{i-2,j+2} + c_{i-1,j-2} f_{i-1,j-2} \\ &+ c_{i-1,j-1} f_{i-1,j-1} + c_{i-1,j} f_{i-1,j} \\ - &+ c_{i-1,j-1} f_{i-1,j-1} + c_{i-1,j} f_{i-1,j} \\ &+ c_{i-1,j+1} f_{i-1,j+1} + c_{i-1,j+2} f_{i-1,j+2} \\ &+ c_{i,j-2} f_{i,j-2} + c_{i,j-1} f_{i,j-1} \\ &+ c_{i,j+1} f_{i,j+1} + c_{i,j+2} f_{i,j+2} \\ @@ -573,9 +572,9 @@ Fourth order approximation (9-point stencil) .. math:: \texttt{ddx\_c} = \frac{-\texttt{c2}_{x+2} + 8\texttt{c2}_{x+1} - - 8\texttt{c2}_{x-1} + \texttt{c2}_{x-1} }{ 12\texttt{c1}\text{d}x} \\ + 8\texttt{c2}_{x-1} + \texttt{c2}_{x-2} }{ 12\texttt{c1}\text{d}x} \\ \texttt{ddz\_c} = \frac{-\texttt{c2}_{z+2} + 8\texttt{c2}_{z+1} - - 8\texttt{c2}_{z-1} + \texttt{c2}_{z-1} }{ 12\texttt{c1}\text{d}z} + 8\texttt{c2}_{z-1} + \texttt{c2}_{z-2} }{ 12\texttt{c1}\text{d}z} This gives diff --git a/manual/sphinx/user_docs/quickstart.rst b/manual/sphinx/user_docs/quickstart.rst index 94ada4d27a..5cf4d3c5bb 100644 --- a/manual/sphinx/user_docs/quickstart.rst +++ b/manual/sphinx/user_docs/quickstart.rst @@ -17,7 +17,7 @@ the following tools and libraries: * ``git`` (>= 2.x) * `CMake `_ -* a C++-14 compiler (for example, GCC >= 5.0) +* a C++-17 compiler (for example, GCC >= 8.0) * an ``MPI`` implementation (for example OpenMPI or MPICH) * The `NetCDF C library `__ diff --git a/requirements.txt b/requirements.txt index 03f43a92d2..dcbe5cef5c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,8 @@ -Jinja2>=2.11.3 -numpy>=1.14.1 -scipy>=1.0.0 -netcdf4>=1.3.1 -matplotlib>=2.0.0 -Cython>=0.29.0 +Jinja2~=3.1.0 +numpy~=2.0.0 +scipy>=1.11.0 +netcdf4~=1.7.1 +matplotlib>=3.7.0 +Cython~=3.0.0 +boututils~=0.2.1 +boutdata~=0.2.1 diff --git a/src/bout++.cxx b/src/bout++.cxx index 127cb6ff4a..ff25b1163e 100644 --- a/src/bout++.cxx +++ b/src/bout++.cxx @@ -4,9 +4,9 @@ * Adapted from the BOUT code by B.Dudson, University of York, Oct 2007 * ************************************************************************** - * Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu + * Copyright 2010-2023 BOUT++ contributors * - * Contact Ben Dudson, bd512@york.ac.uk + * Contact Ben Dudson, dudson2@llnl.gov * * This file is part of BOUT++. * @@ -59,6 +59,10 @@ const char DEFAULT_DIR[] = "data"; #include "bout/bout.hxx" #undef BOUT_NO_USING_NAMESPACE_BOUTGLOBALS +#if BOUT_HAS_ADIOS2 +#include "bout/adios_object.hxx" +#endif + #include #include @@ -161,6 +165,10 @@ int BoutInitialise(int& argc, char**& argv) { savePIDtoFile(args.data_dir, MYPE); +#if BOUT_HAS_ADIOS2 + bout::ADIOSInit(BoutComm::get()); +#endif + // Print the different parts of the startup info printStartupHeader(MYPE, BoutComm::size()); printCompileTimeOptions(); @@ -182,8 +190,7 @@ int BoutInitialise(int& argc, char**& argv) { // but it's possible that only happens in BoutFinalise, which is // too late for that check. const auto datadir = Options::root()["datadir"].withDefault(DEFAULT_DIR); - MAYBE_UNUSED() - const auto optionfile = + [[maybe_unused]] const auto optionfile = Options::root()["optionfile"].withDefault(args.opt_file); const auto settingsfile = Options::root()["settingsfile"].withDefault(args.set_file); @@ -565,6 +572,7 @@ void printCompileTimeOptions() { constexpr auto netcdf_flavour = has_netcdf ? (has_legacy_netcdf ? " (Legacy)" : " (NetCDF4)") : ""; output_info.write(_("\tNetCDF support {}{}\n"), is_enabled(has_netcdf), netcdf_flavour); + output_info.write(_("\tADIOS2 support {}\n"), is_enabled(has_adios2)); output_info.write(_("\tPETSc support {}\n"), is_enabled(has_petsc)); output_info.write(_("\tPretty function name support {}\n"), is_enabled(has_pretty_function)); @@ -574,11 +582,8 @@ void printCompileTimeOptions() { output_info.write(_("\tSUNDIALS support {}\n"), is_enabled(has_sundials)); output_info.write(_("\tBacktrace in exceptions {}\n"), is_enabled(use_backtrace)); output_info.write(_("\tColour in logs {}\n"), is_enabled(use_color)); - output_info.write(_("\tOpenMP parallelisation {}"), is_enabled(use_openmp)); -#ifdef _OPENMP - output_info.write(_(", using {} threads"), omp_get_max_threads()); -#endif - output_info.write("\n"); + output_info.write(_("\tOpenMP parallelisation {}, using {} threads\n"), + is_enabled(use_openmp), omp_get_max_threads()); output_info.write(_("\tExtra debug output {}\n"), is_enabled(use_output_debug)); output_info.write(_("\tFloating-point exceptions {}\n"), is_enabled(use_sigfpe)); output_info.write(_("\tSignal handling support {}\n"), is_enabled(use_signal)); @@ -693,6 +698,7 @@ void addBuildFlagsToOptions(Options& options) { options["has_gettext"].force(bout::build::has_gettext); options["has_lapack"].force(bout::build::has_lapack); options["has_netcdf"].force(bout::build::has_netcdf); + options["has_adios2"].force(bout::build::has_adios2); options["has_petsc"].force(bout::build::has_petsc); options["has_hypre"].force(bout::build::has_hypre); options["has_umpire"].force(bout::build::has_umpire); @@ -706,6 +712,7 @@ void addBuildFlagsToOptions(Options& options) { options["use_backtrace"].force(bout::build::use_backtrace); options["use_color"].force(bout::build::use_color); options["use_openmp"].force(bout::build::use_openmp); + options["openmp_threads"].force(omp_get_max_threads()); options["use_output_debug"].force(bout::build::use_output_debug); options["use_sigfpe"].force(bout::build::use_sigfpe); options["use_signal"].force(bout::build::use_signal); @@ -788,6 +795,10 @@ int BoutFinalise(bool write_settings) { // Call HYPER_Finalize if not already called bout::HypreLib::cleanup(); +#if BOUT_HAS_ADIOS2 + bout::ADIOSFinalize(); +#endif + // MPI communicator, including MPI_Finalize() BoutComm::cleanup(); @@ -823,7 +834,7 @@ BoutMonitor::BoutMonitor(BoutReal timestep, Options& options) .doc(_("Name of file whose existence triggers a stop")) .withDefault("BOUT.stop"))) {} -int BoutMonitor::call(Solver* solver, BoutReal t, MAYBE_UNUSED(int iter), int NOUT) { +int BoutMonitor::call(Solver* solver, BoutReal t, [[maybe_unused]] int iter, int NOUT) { TRACE("BoutMonitor::call({:e}, {:d}, {:d})", t, iter, NOUT); // Increment Solver's iteration counter, and set the global `iteration` diff --git a/src/field/field.cxx b/src/field/field.cxx index 54883c506c..e48a8f3ef7 100644 --- a/src/field/field.cxx +++ b/src/field/field.cxx @@ -23,8 +23,6 @@ * **************************************************************************/ -//#include - #include #include #include diff --git a/src/field/field3d.cxx b/src/field/field3d.cxx index 0bd9e66fc4..4ed9641f44 100644 --- a/src/field/field3d.cxx +++ b/src/field/field3d.cxx @@ -32,6 +32,8 @@ #include +#include "bout/parallel_boundary_op.hxx" +#include "bout/parallel_boundary_region.hxx" #include #include #include @@ -173,7 +175,7 @@ const Field3D& Field3D::ynext(int dir) const { if (dir > 0) { return yup(dir - 1); } else if (dir < 0) { - return ydown(std::abs(dir) - 1); + return ydown(-dir - 1); } else { return *this; } @@ -504,7 +506,7 @@ void Field3D::applyParallelBoundary(const std::string& condition) { /// Loop over the mesh boundary regions for (const auto& reg : fieldmesh->getBoundariesPar()) { auto op = std::unique_ptr{ - dynamic_cast(bfact->create(condition, reg))}; + dynamic_cast(bfact->create(condition, reg.get()))}; op->apply(*this); } } @@ -524,7 +526,7 @@ void Field3D::applyParallelBoundary(const std::string& region, for (const auto& reg : fieldmesh->getBoundariesPar()) { if (reg->label == region) { auto op = std::unique_ptr{ - dynamic_cast(bfact->create(condition, reg))}; + dynamic_cast(bfact->create(condition, reg.get()))}; op->apply(*this); break; } @@ -548,9 +550,9 @@ void Field3D::applyParallelBoundary(const std::string& region, // BoundaryFactory can't create boundaries using Field3Ds, so get temporary // boundary of the right type auto tmp = std::unique_ptr{ - dynamic_cast(bfact->create(condition, reg))}; + dynamic_cast(bfact->create(condition, reg.get()))}; // then clone that with the actual argument - auto op = std::unique_ptr{tmp->clone(reg, f)}; + auto op = std::unique_ptr{tmp->clone(reg.get(), f)}; op->apply(*this); break; } @@ -618,7 +620,7 @@ Field3D filter(const Field3D& var, int N0, const std::string& rgn) { const Region& region = var.getRegion2D(region_str); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { Array f(ncz / 2 + 1); @@ -668,7 +670,7 @@ Field3D lowPass(const Field3D& var, int zmax, bool keep_zonal, const std::string const Region& region = var.getRegion2D(region_str); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { Array f(ncz / 2 + 1); @@ -742,7 +744,7 @@ namespace { #if CHECK > 2 void checkDataIsFiniteOnRegion(const Field3D& f, const std::string& region) { // Do full checks - BOUT_FOR_SERIAL(i, f.getRegion(region)) { + BOUT_FOR_SERIAL(i, f.getValidRegionWithDefault(region)) { if (!finite(f[i])) { throw BoutException("Field3D: Operation on non-finite data at [{:d}][{:d}][{:d}]\n", i.x(), i.y(), i.z()); @@ -819,3 +821,15 @@ void swap(Field3D& first, Field3D& second) noexcept { swap(first.yup_fields, second.yup_fields); swap(first.ydown_fields, second.ydown_fields); } + +const Region& +Field3D::getValidRegionWithDefault(const std::string& region_name) const { + if (regionID.has_value()) { + return fieldmesh->getRegion(regionID.value()); + } + return fieldmesh->getRegion(region_name); +} + +void Field3D::setRegion(const std::string& region_name) { + regionID = fieldmesh->getRegionID(region_name); +} diff --git a/src/field/field_data.cxx b/src/field/field_data.cxx index ee8bd97b30..529f595316 100644 --- a/src/field/field_data.cxx +++ b/src/field/field_data.cxx @@ -1,4 +1,6 @@ +#include "bout/parallel_boundary_op.hxx" +#include "bout/parallel_boundary_region.hxx" #include "bout/unused.hxx" #include #include @@ -151,10 +153,9 @@ void FieldData::setBoundary(const std::string& name) { } /// Get the mesh boundary regions - std::vector par_reg = mesh->getBoundariesPar(); /// Loop over the mesh parallel boundary regions for (const auto& reg : mesh->getBoundariesPar()) { - auto* op = dynamic_cast(bfact->createFromOptions(name, reg)); + auto* op = dynamic_cast(bfact->createFromOptions(name, reg.get())); if (op != nullptr) { bndry_op_par.push_back(op); } diff --git a/src/field/field_factory.cxx b/src/field/field_factory.cxx index fb03c3b174..f65f2e7f55 100644 --- a/src/field/field_factory.cxx +++ b/src/field/field_factory.cxx @@ -93,8 +93,20 @@ FieldFactory::FieldFactory(Mesh* localmesh, Options* opt) // Note: don't use 'options' here because 'options' is a 'const Options*' // pointer, so this would fail if the "input" section is not present. Options& nonconst_options{opt == nullptr ? Options::root() : *opt}; - transform_from_field_aligned = - nonconst_options["input"]["transform_from_field_aligned"].withDefault(true); + + // Convert from string, or FieldFactory is used to parse the string + auto str = + nonconst_options["input"]["transform_from_field_aligned"].withDefault( + "true"); + if ((str == "true") or (str == "True")) { + transform_from_field_aligned = true; + } else if ((str == "false") or (str == "False")) { + transform_from_field_aligned = false; + } else { + throw ParseException( + "Invalid boolean given as input:transform_from_field_aligned: '{:s}'", + nonconst_options["input"]["transform_from_field_aligned"].as()); + } // Convert using stoi rather than Options, or a FieldFactory is used to parse // the string, leading to infinite loop. @@ -114,6 +126,14 @@ FieldFactory::FieldFactory(Mesh* localmesh, Options* opt) addGenerator("pi", std::make_shared(PI)); addGenerator("π", std::make_shared(PI)); + // Boolean values + addGenerator("true", std::make_shared(1)); + addGenerator("false", std::make_shared(0)); + + // Python converts booleans to True/False + addGenerator("True", std::make_shared(1)); + addGenerator("False", std::make_shared(0)); + // Some standard functions addGenerator("sin", std::make_shared>(nullptr, "sin")); addGenerator("cos", std::make_shared>(nullptr, "cos")); diff --git a/src/field/fieldgenerators.hxx b/src/field/fieldgenerators.hxx index 66ef11a855..2485b4b82d 100644 --- a/src/field/fieldgenerators.hxx +++ b/src/field/fieldgenerators.hxx @@ -4,8 +4,8 @@ * These classes are used by FieldFactory */ -#ifndef __FIELDGENERATORS_H__ -#define __FIELDGENERATORS_H__ +#ifndef BOUT_FIELDGENERATORS_H +#define BOUT_FIELDGENERATORS_H #include #include @@ -352,4 +352,4 @@ private: FieldGeneratorPtr test, gt0, lt0; }; -#endif // __FIELDGENERATORS_H__ +#endif // BOUT_FIELDGENERATORS_H diff --git a/src/field/gen_fieldops.jinja b/src/field/gen_fieldops.jinja index 249245b21c..ecd4e628cc 100644 --- a/src/field/gen_fieldops.jinja +++ b/src/field/gen_fieldops.jinja @@ -8,6 +8,17 @@ checkData({{lhs.name}}); checkData({{rhs.name}}); + {% if out == "Field3D" %} + {% if lhs == rhs == "Field3D" %} + {{out.name}}.setRegion({{lhs.name}}.getMesh()->getCommonRegion({{lhs.name}}.getRegionID(), + {{rhs.name}}.getRegionID())); + {% elif lhs == "Field3D" %} + {{out.name}}.setRegion({{lhs.name}}.getRegionID()); + {% elif rhs == "Field3D" %} + {{out.name}}.setRegion({{rhs.name}}.getRegionID()); + {% endif %} + {% endif %} + {% if (out == "Field3D") and ((lhs == "Field2D") or (rhs =="Field2D")) %} Mesh *localmesh = {{lhs.name if lhs.field_type != "BoutReal" else rhs.name}}.getMesh(); @@ -41,11 +52,11 @@ } {% elif (operator == "/") and (rhs == "BoutReal") %} const auto tmp = 1.0 / {{rhs.index}}; - {{region_loop}}({{index_var}}, {{out.name}}.getRegion({{region_name}})) { + {{region_loop}}({{index_var}}, {{out.name}}.getValidRegionWithDefault({{region_name}})) { {{out.index}} = {{lhs.index}} * tmp; } {% else %} - {{region_loop}}({{index_var}}, {{out.name}}.getRegion({{region_name}})) { + {{region_loop}}({{index_var}}, {{out.name}}.getValidRegionWithDefault({{region_name}})) { {{out.index}} = {{lhs.index}} {{operator}} {{rhs.index}}; } {% endif %} @@ -73,6 +84,11 @@ checkData(*this); checkData({{rhs.name}}); + {% if lhs == rhs == "Field3D" %} + regionID = fieldmesh->getCommonRegion(regionID, {{rhs.name}}.regionID); + {% endif %} + + {% if (lhs == "Field3D") and (rhs =="Field2D") %} {{region_loop}}({{index_var}}, {{rhs.name}}.getRegion({{region_name}})) { const auto {{mixed_base_ind}} = fieldmesh->ind2Dto3D({{index_var}}); diff --git a/src/field/generated_fieldops.cxx b/src/field/generated_fieldops.cxx index a3613eca3e..6b778acee3 100644 --- a/src/field/generated_fieldops.cxx +++ b/src/field/generated_fieldops.cxx @@ -14,7 +14,9 @@ Field3D operator*(const Field3D& lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] * rhs[index]; } @@ -36,6 +38,8 @@ Field3D& Field3D::operator*=(const Field3D& rhs) { checkData(*this); checkData(rhs); + regionID = fieldmesh->getCommonRegion(regionID, rhs.regionID); + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] *= rhs[index]; } checkData(*this); @@ -54,7 +58,9 @@ Field3D operator/(const Field3D& lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] / rhs[index]; } @@ -76,6 +82,8 @@ Field3D& Field3D::operator/=(const Field3D& rhs) { checkData(*this); checkData(rhs); + regionID = fieldmesh->getCommonRegion(regionID, rhs.regionID); + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] /= rhs[index]; } checkData(*this); @@ -94,7 +102,9 @@ Field3D operator+(const Field3D& lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] + rhs[index]; } @@ -116,6 +126,8 @@ Field3D& Field3D::operator+=(const Field3D& rhs) { checkData(*this); checkData(rhs); + regionID = fieldmesh->getCommonRegion(regionID, rhs.regionID); + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] += rhs[index]; } checkData(*this); @@ -134,7 +146,9 @@ Field3D operator-(const Field3D& lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] - rhs[index]; } @@ -156,6 +170,8 @@ Field3D& Field3D::operator-=(const Field3D& rhs) { checkData(*this); checkData(rhs); + regionID = fieldmesh->getCommonRegion(regionID, rhs.regionID); + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] -= rhs[index]; } checkData(*this); @@ -174,6 +190,8 @@ Field3D operator*(const Field3D& lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); + result.setRegion(lhs.getRegionID()); + Mesh* localmesh = lhs.getMesh(); BOUT_FOR(index, rhs.getRegion("RGN_ALL")) { @@ -224,6 +242,8 @@ Field3D operator/(const Field3D& lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); + result.setRegion(lhs.getRegionID()); + Mesh* localmesh = lhs.getMesh(); BOUT_FOR(index, rhs.getRegion("RGN_ALL")) { @@ -276,6 +296,8 @@ Field3D operator+(const Field3D& lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); + result.setRegion(lhs.getRegionID()); + Mesh* localmesh = lhs.getMesh(); BOUT_FOR(index, rhs.getRegion("RGN_ALL")) { @@ -326,6 +348,8 @@ Field3D operator-(const Field3D& lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); + result.setRegion(lhs.getRegionID()); + Mesh* localmesh = lhs.getMesh(); BOUT_FOR(index, rhs.getRegion("RGN_ALL")) { @@ -455,7 +479,11 @@ Field3D operator*(const Field3D& lhs, const BoutReal rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] * rhs; } + result.setRegion(lhs.getRegionID()); + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] * rhs; + } checkData(result); return result; @@ -491,8 +519,12 @@ Field3D operator/(const Field3D& lhs, const BoutReal rhs) { checkData(lhs); checkData(rhs); + result.setRegion(lhs.getRegionID()); + const auto tmp = 1.0 / rhs; - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] * tmp; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] * tmp; + } checkData(result); return result; @@ -529,7 +561,11 @@ Field3D operator+(const Field3D& lhs, const BoutReal rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] + rhs; } + result.setRegion(lhs.getRegionID()); + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] + rhs; + } checkData(result); return result; @@ -565,7 +601,11 @@ Field3D operator-(const Field3D& lhs, const BoutReal rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] - rhs; } + result.setRegion(lhs.getRegionID()); + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] - rhs; + } checkData(result); return result; @@ -602,6 +642,8 @@ Field3D operator*(const Field2D& lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); + result.setRegion(rhs.getRegionID()); + Mesh* localmesh = lhs.getMesh(); BOUT_FOR(index, lhs.getRegion("RGN_ALL")) { @@ -623,6 +665,8 @@ Field3D operator/(const Field2D& lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); + result.setRegion(rhs.getRegionID()); + Mesh* localmesh = lhs.getMesh(); BOUT_FOR(index, lhs.getRegion("RGN_ALL")) { @@ -644,6 +688,8 @@ Field3D operator+(const Field2D& lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); + result.setRegion(rhs.getRegionID()); + Mesh* localmesh = lhs.getMesh(); BOUT_FOR(index, lhs.getRegion("RGN_ALL")) { @@ -665,6 +711,8 @@ Field3D operator-(const Field2D& lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); + result.setRegion(rhs.getRegionID()); + Mesh* localmesh = lhs.getMesh(); BOUT_FOR(index, lhs.getRegion("RGN_ALL")) { @@ -686,7 +734,7 @@ Field2D operator*(const Field2D& lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] * rhs[index]; } @@ -722,7 +770,7 @@ Field2D operator/(const Field2D& lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] / rhs[index]; } @@ -758,7 +806,7 @@ Field2D operator+(const Field2D& lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] + rhs[index]; } @@ -794,7 +842,7 @@ Field2D operator-(const Field2D& lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] - rhs[index]; } @@ -909,7 +957,9 @@ Field2D operator*(const Field2D& lhs, const BoutReal rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] * rhs; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] * rhs; + } checkData(result); return result; @@ -942,7 +992,9 @@ Field2D operator/(const Field2D& lhs, const BoutReal rhs) { checkData(rhs); const auto tmp = 1.0 / rhs; - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] * tmp; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] * tmp; + } checkData(result); return result; @@ -975,7 +1027,9 @@ Field2D operator+(const Field2D& lhs, const BoutReal rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] + rhs; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] + rhs; + } checkData(result); return result; @@ -1007,7 +1061,9 @@ Field2D operator-(const Field2D& lhs, const BoutReal rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] - rhs; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] - rhs; + } checkData(result); return result; @@ -1408,7 +1464,7 @@ FieldPerp operator*(const FieldPerp& lhs, const FieldPerp& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] * rhs[index]; } @@ -1444,7 +1500,7 @@ FieldPerp operator/(const FieldPerp& lhs, const FieldPerp& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] / rhs[index]; } @@ -1480,7 +1536,7 @@ FieldPerp operator+(const FieldPerp& lhs, const FieldPerp& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] + rhs[index]; } @@ -1516,7 +1572,7 @@ FieldPerp operator-(const FieldPerp& lhs, const FieldPerp& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] - rhs[index]; } @@ -1551,7 +1607,9 @@ FieldPerp operator*(const FieldPerp& lhs, const BoutReal rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] * rhs; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] * rhs; + } checkData(result); return result; @@ -1584,7 +1642,9 @@ FieldPerp operator/(const FieldPerp& lhs, const BoutReal rhs) { checkData(rhs); const auto tmp = 1.0 / rhs; - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] * tmp; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] * tmp; + } checkData(result); return result; @@ -1616,7 +1676,9 @@ FieldPerp operator+(const FieldPerp& lhs, const BoutReal rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] + rhs; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] + rhs; + } checkData(result); return result; @@ -1648,7 +1710,9 @@ FieldPerp operator-(const FieldPerp& lhs, const BoutReal rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs[index] - rhs; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] - rhs; + } checkData(result); return result; @@ -1680,7 +1744,11 @@ Field3D operator*(const BoutReal lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs * rhs[index]; } + result.setRegion(rhs.getRegionID()); + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs * rhs[index]; + } checkData(result); return result; @@ -1693,7 +1761,11 @@ Field3D operator/(const BoutReal lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs / rhs[index]; } + result.setRegion(rhs.getRegionID()); + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs / rhs[index]; + } checkData(result); return result; @@ -1706,7 +1778,11 @@ Field3D operator+(const BoutReal lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs + rhs[index]; } + result.setRegion(rhs.getRegionID()); + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs + rhs[index]; + } checkData(result); return result; @@ -1719,7 +1795,11 @@ Field3D operator-(const BoutReal lhs, const Field3D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs - rhs[index]; } + result.setRegion(rhs.getRegionID()); + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs - rhs[index]; + } checkData(result); return result; @@ -1732,7 +1812,9 @@ Field2D operator*(const BoutReal lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs * rhs[index]; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs * rhs[index]; + } checkData(result); return result; @@ -1745,7 +1827,9 @@ Field2D operator/(const BoutReal lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs / rhs[index]; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs / rhs[index]; + } checkData(result); return result; @@ -1758,7 +1842,9 @@ Field2D operator+(const BoutReal lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs + rhs[index]; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs + rhs[index]; + } checkData(result); return result; @@ -1771,7 +1857,9 @@ Field2D operator-(const BoutReal lhs, const Field2D& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs - rhs[index]; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs - rhs[index]; + } checkData(result); return result; @@ -1784,7 +1872,9 @@ FieldPerp operator*(const BoutReal lhs, const FieldPerp& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs * rhs[index]; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs * rhs[index]; + } checkData(result); return result; @@ -1797,7 +1887,9 @@ FieldPerp operator/(const BoutReal lhs, const FieldPerp& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs / rhs[index]; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs / rhs[index]; + } checkData(result); return result; @@ -1810,7 +1902,9 @@ FieldPerp operator+(const BoutReal lhs, const FieldPerp& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs + rhs[index]; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs + rhs[index]; + } checkData(result); return result; @@ -1823,7 +1917,9 @@ FieldPerp operator-(const BoutReal lhs, const FieldPerp& rhs) { checkData(lhs); checkData(rhs); - BOUT_FOR(index, result.getRegion("RGN_ALL")) { result[index] = lhs - rhs[index]; } + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs - rhs[index]; + } checkData(result); return result; diff --git a/src/field/makefile b/src/field/makefile deleted file mode 100644 index acefa6bbce..0000000000 --- a/src/field/makefile +++ /dev/null @@ -1,23 +0,0 @@ - -BOUT_TOP = ../.. - -SOURCEC = field.cxx field2d.cxx field3d.cxx fieldperp.cxx field_data.cxx \ - fieldgroup.cxx field_factory.cxx fieldgenerators.cxx \ - initialprofiles.cxx vecops.cxx vector2d.cxx vector3d.cxx \ - where.cxx globalfield.cxx generated_fieldops.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) field_data.hxx -TARGET = lib - - -include $(BOUT_TOP)/make.config - -# The C++ source file depends on both the Python driver and the Jinja -# template files. If either have changed, run the driver (first -# dependency), dumping the output in the C++ target file. We then try -# to apply clang-format to this file in-place, but don't worry if the -# formatting fails -generated_fieldops.cxx: gen_fieldops.py gen_fieldops.jinja - @echo " Generating $@" - @./$< --filename $@.tmp || (fail=$?; echo "touch $@ to ignore failed generation" ; exit $fail) - @mv $@.tmp $@ - @clang-format -i $@ || echo "Formatting failed" diff --git a/src/fmt/makefile b/src/fmt/makefile deleted file mode 100644 index 96c557e412..0000000000 --- a/src/fmt/makefile +++ /dev/null @@ -1,7 +0,0 @@ - -BOUT_TOP = ../.. - -SOURCEC = format.cxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/fft_fftw.cxx b/src/invert/fft_fftw.cxx index f158fa3d7a..d66f35beee 100644 --- a/src/invert/fft_fftw.cxx +++ b/src/invert/fft_fftw.cxx @@ -106,8 +106,8 @@ void fft_init(bool fft_measure) { #if !BOUT_USE_OPENMP // Serial code -void rfft(MAYBE_UNUSED(const BoutReal* in), MAYBE_UNUSED(int length), - MAYBE_UNUSED(dcomplex* out)) { +void rfft([[maybe_unused]] const BoutReal* in, [[maybe_unused]] int length, + [[maybe_unused]] dcomplex* out) { #if !BOUT_HAS_FFTW throw BoutException("This instance of BOUT++ has been compiled without fftw support."); #else @@ -170,8 +170,8 @@ void rfft(MAYBE_UNUSED(const BoutReal* in), MAYBE_UNUSED(int length), #endif } -void irfft(MAYBE_UNUSED(const dcomplex* in), MAYBE_UNUSED(int length), - MAYBE_UNUSED(BoutReal* out)) { +void irfft([[maybe_unused]] const dcomplex* in, [[maybe_unused]] int length, + [[maybe_unused]] BoutReal* out) { #if !BOUT_HAS_FFTW throw BoutException("This instance of BOUT++ has been compiled without fftw support."); #else @@ -233,8 +233,8 @@ void irfft(MAYBE_UNUSED(const dcomplex* in), MAYBE_UNUSED(int length), } #else // Parallel thread-safe version of rfft and irfft -void rfft(MAYBE_UNUSED(const BoutReal* in), MAYBE_UNUSED(int length), - MAYBE_UNUSED(dcomplex* out)) { +void rfft([[maybe_unused]] const BoutReal* in, [[maybe_unused]] int length, + [[maybe_unused]] dcomplex* out) { #if !BOUT_HAS_FFTW throw BoutException("This instance of BOUT++ has been compiled without fftw support."); #else @@ -258,7 +258,7 @@ void rfft(MAYBE_UNUSED(const BoutReal* in), MAYBE_UNUSED(int length), // use a `single` block here as that requires all threads to reach the // block (implicit barrier) which may not be true in all cases (e.g. // if there are 8 threads but only 4 call the fft routine). - BOUT_OMP(critical(rfft)) + BOUT_OMP_SAFE(critical(rfft)) if ((size != length) || (nthreads < n_th)) { if (size > 0) { // Free all memory @@ -312,8 +312,8 @@ void rfft(MAYBE_UNUSED(const BoutReal* in), MAYBE_UNUSED(int length), #endif } -void irfft(MAYBE_UNUSED(const dcomplex* in), MAYBE_UNUSED(int length), - MAYBE_UNUSED(BoutReal* out)) { +void irfft([[maybe_unused]] const dcomplex* in, [[maybe_unused]] int length, + [[maybe_unused]] BoutReal* out) { #if !BOUT_HAS_FFTW throw BoutException("This instance of BOUT++ has been compiled without fftw support."); #else @@ -335,7 +335,7 @@ void irfft(MAYBE_UNUSED(const dcomplex* in), MAYBE_UNUSED(int length), // use a `single` block here as that requires all threads to reach the // block (implicit barrier) which may not be true in all cases (e.g. // if there are 8 threads but only 4 call the fft routine). - BOUT_OMP(critical(irfft)) + BOUT_OMP_SAFE(critical(irfft)) if ((size != length) || (nthreads < n_th)) { if (size > 0) { // Free all memory @@ -388,8 +388,8 @@ void irfft(MAYBE_UNUSED(const dcomplex* in), MAYBE_UNUSED(int length), #endif // Discrete sine transforms (B Shanahan) -void DST(MAYBE_UNUSED(const BoutReal* in), MAYBE_UNUSED(int length), - MAYBE_UNUSED(dcomplex* out)) { +void DST([[maybe_unused]] const BoutReal* in, [[maybe_unused]] int length, + [[maybe_unused]] dcomplex* out) { #if !BOUT_HAS_FFTW throw BoutException("This instance of BOUT++ has been compiled without fftw support."); #else @@ -446,8 +446,8 @@ void DST(MAYBE_UNUSED(const BoutReal* in), MAYBE_UNUSED(int length), #endif } -void DST_rev(MAYBE_UNUSED(dcomplex* in), MAYBE_UNUSED(int length), - MAYBE_UNUSED(BoutReal* out)) { +void DST_rev([[maybe_unused]] dcomplex* in, [[maybe_unused]] int length, + [[maybe_unused]] BoutReal* out) { #if !BOUT_HAS_FFTW throw BoutException("This instance of BOUT++ has been compiled without fftw support."); #else diff --git a/src/invert/laplace/impls/cyclic/cyclic_laplace.cxx b/src/invert/laplace/impls/cyclic/cyclic_laplace.cxx index 2687bf7187..5ce4e540b7 100644 --- a/src/invert/laplace/impls/cyclic/cyclic_laplace.cxx +++ b/src/invert/laplace/impls/cyclic/cyclic_laplace.cxx @@ -33,11 +33,13 @@ * */ -#include "cyclic_laplace.hxx" -#include "bout/build_config.hxx" +#include "bout/build_defines.hxx" #if not BOUT_USE_METRIC_3D +#include "cyclic_laplace.hxx" +#include "bout/assert.hxx" +#include "bout/bout_types.hxx" #include #include #include @@ -47,7 +49,7 @@ #include #include -#include "cyclic_laplace.hxx" +#include LaplaceCyclic::LaplaceCyclic(Options* opt, const CELL_LOC loc, Mesh* mesh_in, Solver* UNUSED(solver)) @@ -120,18 +122,18 @@ FieldPerp LaplaceCyclic::solve(const FieldPerp& rhs, const FieldPerp& x0) { // If the flags to assign that only one guard cell should be used is set int inbndry = localmesh->xstart, outbndry = localmesh->xstart; - if (((global_flags & INVERT_BOTH_BNDRY_ONE) != 0) || (localmesh->xstart < 2)) { + if (isGlobalFlagSet(INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { inbndry = outbndry = 1; } - if ((inner_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isInnerBoundaryFlagSet(INVERT_BNDRY_ONE)) { inbndry = 1; } - if ((outer_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isOuterBoundaryFlagSet(INVERT_BNDRY_ONE)) { outbndry = 1; } if (dst) { - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array( @@ -139,13 +141,13 @@ FieldPerp LaplaceCyclic::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Loop over X indices, including boundaries but not guard cells. (unless periodic // in x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ix = xs; ix <= xe; ix++) { // Take DST in Z direction and put result in k1d - if (((ix < inbndry) && (inner_boundary_flags & INVERT_SET) && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && (outer_boundary_flags & INVERT_SET) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary DST(x0[ix] + 1, localmesh->LocalNz - 2, std::begin(k1d)); } else { @@ -161,7 +163,7 @@ FieldPerp LaplaceCyclic::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Get elements of the tridiagonal matrix // including boundary conditions BoutReal zlen = getUniform(coords->dz) * (localmesh->LocalNz - 3); - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int kz = 0; kz < nmode; kz++) { // wave number is 1/[rad]; DST has extra 2. BoutReal kwave = kz * 2.0 * PI / (2. * zlen); @@ -169,8 +171,7 @@ FieldPerp LaplaceCyclic::solve(const FieldPerp& rhs, const FieldPerp& x0) { tridagMatrix(&a(kz, 0), &b(kz, 0), &c(kz, 0), &bcmplx(kz, 0), jy, kz, // wave number index kwave, // kwave (inverse wave length) - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false, // Don't include guard cells in arrays false); // Z domain not periodic } @@ -181,14 +182,14 @@ FieldPerp LaplaceCyclic::solve(const FieldPerp& rhs, const FieldPerp& x0) { cr->solve(bcmplx, xcmplx); // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array // ZFFT routine expects input of this length auto k1d = Array(localmesh->LocalNz); - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ix = xs; ix <= xe; ix++) { for (int kz = 0; kz < nmode; kz++) { k1d[kz] = xcmplx(kz, ix - xs); @@ -206,7 +207,7 @@ FieldPerp LaplaceCyclic::solve(const FieldPerp& rhs, const FieldPerp& x0) { } } else { const BoutReal zlength = getUniform(coords->zlength()); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array // ZFFT routine expects input of this length @@ -214,13 +215,13 @@ FieldPerp LaplaceCyclic::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Loop over X indices, including boundaries but not guard // cells (unless periodic in x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ix = xs; ix <= xe; ix++) { // Take FFT in Z direction, apply shift, and put result in k1d - if (((ix < inbndry) && (inner_boundary_flags & INVERT_SET) && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && (outer_boundary_flags & INVERT_SET) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary rfft(x0[ix], localmesh->LocalNz, std::begin(k1d)); } else { @@ -235,14 +236,13 @@ FieldPerp LaplaceCyclic::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Get elements of the tridiagonal matrix // including boundary conditions - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int kz = 0; kz < nmode; kz++) { BoutReal kwave = kz * 2.0 * PI / zlength; // wave number is 1/[rad] tridagMatrix(&a(kz, 0), &b(kz, 0), &c(kz, 0), &bcmplx(kz, 0), jy, kz, // True for the component constant (DC) in Z kwave, // Z wave number - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false); // Don't include guard cells in arrays } } @@ -269,15 +269,15 @@ FieldPerp LaplaceCyclic::solve(const FieldPerp& rhs, const FieldPerp& x0) { } // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array // ZFFT routine expects input of this length auto k1d = Array((localmesh->LocalNz) / 2 + 1); - const bool zero_DC = (global_flags & INVERT_ZERO_DC) != 0; + const bool zero_DC = isGlobalFlagSet(INVERT_ZERO_DC); - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ix = xs; ix <= xe; ix++) { if (zero_DC) { k1d[0] = 0.; @@ -316,13 +316,13 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { // If the flags to assign that only one guard cell should be used is set int inbndry = localmesh->xstart, outbndry = localmesh->xstart; - if (((global_flags & INVERT_BOTH_BNDRY_ONE) != 0) || (localmesh->xstart < 2)) { + if (isGlobalFlagSet(INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { inbndry = outbndry = 1; } - if ((inner_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isInnerBoundaryFlagSet(INVERT_BNDRY_ONE)) { inbndry = 1; } - if ((outer_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isOuterBoundaryFlagSet(INVERT_BNDRY_ONE)) { outbndry = 1; } @@ -350,6 +350,9 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { const int nsys = nmode * ny; // Number of systems of equations to solve const int nxny = nx * ny; // Number of points in X-Y + // This is just to silence static analysis + ASSERT0(ny > 0); + auto a3D = Matrix(nsys, nx); auto b3D = Matrix(nsys, nx); auto c3D = Matrix(nsys, nx); @@ -358,7 +361,7 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { auto bcmplx3D = Matrix(nsys, nx); if (dst) { - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array // ZFFT routine expects input of this length @@ -366,7 +369,7 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { // Loop over X and Y indices, including boundaries but not guard cells. // (unless periodic in x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ind = 0; ind < nxny; ++ind) { // ind = (ix - xs)*(ye - ys + 1) + (iy - ys) int ix = xs + ind / ny; @@ -374,10 +377,9 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { // Take DST in Z direction and put result in k1d - if (((ix < inbndry) && ((inner_boundary_flags & INVERT_SET) != 0) - && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && ((outer_boundary_flags & INVERT_SET) != 0) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary DST(x0(ix, iy) + 1, localmesh->LocalNz - 2, std::begin(k1d)); } else { @@ -393,7 +395,7 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { // Get elements of the tridiagonal matrix // including boundary conditions const BoutReal zlen = getUniform(coords->dz) * (localmesh->LocalNz - 3); - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nsys; ind++) { // ind = (iy - ys) * nmode + kz int iy = ys + ind / nmode; @@ -405,8 +407,7 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { tridagMatrix(&a3D(ind, 0), &b3D(ind, 0), &c3D(ind, 0), &bcmplx3D(ind, 0), iy, kz, // wave number index kwave, // kwave (inverse wave length) - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false, // Don't include guard cells in arrays false); // Z domain not periodic } @@ -417,13 +418,13 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { cr->solve(bcmplx3D, xcmplx3D); // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array // ZFFT routine expects input of length LocalNz auto k1d = Array(localmesh->LocalNz); - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nxny; ++ind) { // Loop over X and Y // ind = (ix - xs)*(ye - ys + 1) + (iy - ys) int ix = xs + ind / ny; @@ -445,7 +446,7 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { } } else { const BoutReal zlength = getUniform(coords->zlength()); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array // ZFFT routine expects input of this length @@ -454,7 +455,7 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { // Loop over X and Y indices, including boundaries but not guard cells // (unless periodic in x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ind = 0; ind < nxny; ++ind) { // ind = (ix - xs)*(ye - ys + 1) + (iy - ys) int ix = xs + ind / ny; @@ -462,10 +463,9 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { // Take FFT in Z direction, apply shift, and put result in k1d - if (((ix < inbndry) && ((inner_boundary_flags & INVERT_SET) != 0) - && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && ((outer_boundary_flags & INVERT_SET) != 0) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary rfft(x0(ix, iy), localmesh->LocalNz, std::begin(k1d)); } else { @@ -480,7 +480,7 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { // Get elements of the tridiagonal matrix // including boundary conditions - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nsys; ind++) { // ind = (iy - ys) * nmode + kz int iy = ys + ind / nmode; @@ -490,8 +490,7 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { tridagMatrix(&a3D(ind, 0), &b3D(ind, 0), &c3D(ind, 0), &bcmplx3D(ind, 0), iy, kz, // True for the component constant (DC) in Z kwave, // Z wave number - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false); // Don't include guard cells in arrays } } @@ -502,9 +501,8 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { if (localmesh->periodicX) { // Subtract X average of kz=0 mode - BoutReal local[ny + 1]; + std::vector local(ny + 1, 0.0); for (int y = 0; y < ny; y++) { - local[y] = 0.0; for (int ix = xs; ix <= xe; ix++) { local[y] += xcmplx3D(y * nmode, ix - xs).real(); } @@ -512,8 +510,9 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { local[ny] = static_cast(xe - xs + 1); // Global reduce - BoutReal global[ny + 1]; - MPI_Allreduce(local, global, ny + 1, MPI_DOUBLE, MPI_SUM, localmesh->getXcomm()); + std::vector global(ny + 1, 0.0); + MPI_Allreduce(local.data(), global.data(), ny + 1, MPI_DOUBLE, MPI_SUM, + localmesh->getXcomm()); // Subtract average from kz=0 modes for (int y = 0; y < ny; y++) { BoutReal avg = global[y] / global[ny]; @@ -524,15 +523,15 @@ Field3D LaplaceCyclic::solve(const Field3D& rhs, const Field3D& x0) { } // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array((localmesh->LocalNz) / 2 + 1); // ZFFT routine expects input of this length - const bool zero_DC = (global_flags & INVERT_ZERO_DC) != 0; + const bool zero_DC = isGlobalFlagSet(INVERT_ZERO_DC); - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nxny; ++ind) { // Loop over X and Y // ind = (ix - xs)*(ye - ys + 1) + (iy - ys) int ix = xs + ind / ny; diff --git a/src/invert/laplace/impls/cyclic/cyclic_laplace.hxx b/src/invert/laplace/impls/cyclic/cyclic_laplace.hxx index 841f0a4e05..febffa7d18 100644 --- a/src/invert/laplace/impls/cyclic/cyclic_laplace.hxx +++ b/src/invert/laplace/impls/cyclic/cyclic_laplace.hxx @@ -28,8 +28,8 @@ class LaplaceCyclic; -#ifndef __LAP_CYCLIC_H__ -#define __LAP_CYCLIC_H__ +#ifndef BOUT_LAP_CYCLIC_H +#define BOUT_LAP_CYCLIC_H #include "bout/build_config.hxx" #include "bout/invert_laplace.hxx" @@ -125,4 +125,4 @@ private: #endif // BOUT_USE_METRIC_3D -#endif // __SPT_H__ +#endif // BOUT_LAP_CYCLIC_H diff --git a/src/invert/laplace/impls/cyclic/makefile b/src/invert/laplace/impls/cyclic/makefile deleted file mode 100644 index f819d70781..0000000000 --- a/src/invert/laplace/impls/cyclic/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = cyclic_laplace.cxx -SOURCEH = cyclic_laplace.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/hypre3d/hypre3d_laplace.cxx b/src/invert/laplace/impls/hypre3d/hypre3d_laplace.cxx index f99a8a8020..d789e5e408 100644 --- a/src/invert/laplace/impls/hypre3d/hypre3d_laplace.cxx +++ b/src/invert/laplace/impls/hypre3d/hypre3d_laplace.cxx @@ -39,7 +39,8 @@ #include #include #include -#include + +#include LaplaceHypre3d::LaplaceHypre3d(Options* opt, const CELL_LOC loc, Mesh* mesh_in, Solver* solver) @@ -98,7 +99,7 @@ LaplaceHypre3d::LaplaceHypre3d(Options* opt, const CELL_LOC loc, Mesh* mesh_in, // Set up boundary conditions in operator BOUT_FOR_SERIAL(i, indexer->getRegionInnerX()) { - if (inner_boundary_flags & INVERT_AC_GRAD) { + if (isInnerBoundaryFlagSet(INVERT_AC_GRAD)) { // Neumann on inner X boundary operator3D(i, i) = -1. / coords->dx[i] / sqrt(coords->g_11[i]); operator3D(i, i.xp()) = 1. / coords->dx[i] / sqrt(coords->g_11[i]); @@ -110,7 +111,7 @@ LaplaceHypre3d::LaplaceHypre3d(Options* opt, const CELL_LOC loc, Mesh* mesh_in, } BOUT_FOR_SERIAL(i, indexer->getRegionOuterX()) { - if (outer_boundary_flags & INVERT_AC_GRAD) { + if (isOuterBoundaryFlagSet(INVERT_AC_GRAD)) { // Neumann on outer X boundary operator3D(i, i) = 1. / coords->dx[i] / sqrt(coords->g_11[i]); operator3D(i, i.xm()) = -1. / coords->dx[i] / sqrt(coords->g_11[i]); @@ -146,14 +147,12 @@ LaplaceHypre3d::LaplaceHypre3d(Options* opt, const CELL_LOC loc, Mesh* mesh_in, } // FIXME: This needs to be converted to outputVars - if (solver == nullptr or dump == nullptr) { - output_warn << "Warning: Need to pass both a Solver and a Datafile to " + if (solver == nullptr) { + output_warn << "Warning: Need to pass a Solver to " "Laplacian::create() to get iteration counts in the output." << endl; } else { solver->addMonitor(&monitor); - auto name = opt->name(); - dump->addRepeat(average_iterations, name + "_average_iterations"); } } @@ -181,42 +180,42 @@ Field3D LaplaceHypre3d::solve(const Field3D& b_in, const Field3D& x0) { // Adjust vectors to represent boundary conditions and check that // boundary cells are finite BOUT_FOR_SERIAL(i, indexer->getRegionInnerX()) { - const BoutReal val = (inner_boundary_flags & INVERT_SET) ? x0[i] : 0.; - ASSERT1(finite(val)); - if (!(inner_boundary_flags & INVERT_RHS)) { + const BoutReal val = isInnerBoundaryFlagSet(INVERT_SET) ? x0[i] : 0.; + ASSERT1(std::isfinite(val)); + if (!(isInnerBoundaryFlagSet(INVERT_RHS))) { b[i] = val; } else { - ASSERT1(finite(b[i])); + ASSERT1(std::isfinite(b[i])); } } BOUT_FOR_SERIAL(i, indexer->getRegionOuterX()) { - const BoutReal val = (outer_boundary_flags & INVERT_SET) ? x0[i] : 0.; - ASSERT1(finite(val)); - if (!(outer_boundary_flags & INVERT_RHS)) { + const BoutReal val = (isOuterBoundaryFlagSet(INVERT_SET)) ? x0[i] : 0.; + ASSERT1(std::isfinite(val)); + if (!(isOuterBoundaryFlagSet(INVERT_RHS))) { b[i] = val; } else { - ASSERT1(finite(b[i])); + ASSERT1(std::isfinite(b[i])); } } BOUT_FOR_SERIAL(i, indexer->getRegionLowerY()) { const BoutReal val = (lower_boundary_flags & INVERT_SET) ? x0[i] : 0.; - ASSERT1(finite(val)); + ASSERT1(std::isfinite(val)); if (!(lower_boundary_flags & INVERT_RHS)) { b[i] = val; } else { - ASSERT1(finite(b[i])); + ASSERT1(std::isfinite(b[i])); } } BOUT_FOR_SERIAL(i, indexer->getRegionUpperY()) { const BoutReal val = (upper_boundary_flags & INVERT_SET) ? x0[i] : 0.; - ASSERT1(finite(val)); + ASSERT1(std::isfinite(val)); if (!(upper_boundary_flags & INVERT_RHS)) { b[i] = val; } else { - ASSERT1(finite(b[i])); + ASSERT1(std::isfinite(b[i])); } } CALI_MARK_END("LaplaceHypre3d_solve:AdjustBoundary"); diff --git a/src/invert/laplace/impls/hypre3d/hypre3d_laplace.hxx b/src/invert/laplace/impls/hypre3d/hypre3d_laplace.hxx index c9c44ac19e..05a0604c4f 100644 --- a/src/invert/laplace/impls/hypre3d/hypre3d_laplace.hxx +++ b/src/invert/laplace/impls/hypre3d/hypre3d_laplace.hxx @@ -30,8 +30,8 @@ class LaplaceHypre3d; #include "bout/build_config.hxx" -#ifndef __LAPLACE_HYPRE3D_H__ -#define __LAPLACE_HYPRE3D_H__ +#ifndef BOUT_LAPLACE_HYPRE3D_H +#define BOUT_LAPLACE_HYPRE3D_H #if BOUT_HAS_HYPRE @@ -227,4 +227,4 @@ public: #endif // BOUT_HAS_HYPRE -#endif //__LAPLACE_HYPRE3D_H__ +#endif //BOUT_LAPLACE_HYPRE3D_H diff --git a/src/invert/laplace/impls/hypre3d/makefile b/src/invert/laplace/impls/hypre3d/makefile deleted file mode 100644 index 5181eebf98..0000000000 --- a/src/invert/laplace/impls/hypre3d/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = hypre3d_laplace.cxx -SOURCEH = hypre3d_laplace.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/iterative_parallel_tri/iterative_parallel_tri.cxx b/src/invert/laplace/impls/iterative_parallel_tri/iterative_parallel_tri.cxx index 2457ff3b8e..f79463769a 100644 --- a/src/invert/laplace/impls/iterative_parallel_tri/iterative_parallel_tri.cxx +++ b/src/invert/laplace/impls/iterative_parallel_tri/iterative_parallel_tri.cxx @@ -293,12 +293,10 @@ FieldPerp LaplaceIPT::solve(const FieldPerp& b, const FieldPerp& x0) { */ auto bcmplx = Matrix(nmode, ncx); - const bool invert_inner_boundary = - isInnerBoundaryFlagSet(INVERT_SET) and localmesh->firstX(); - const bool invert_outer_boundary = - isOuterBoundaryFlagSet(INVERT_SET) and localmesh->lastX(); + const bool invert_inner_boundary = isInnerBoundaryFlagSetOnFirstX(INVERT_SET); + const bool invert_outer_boundary = isOuterBoundaryFlagSetOnLastX(INVERT_SET); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int ix = 0; ix < ncx; ix++) { /* This for loop will set the bk (initialized by the constructor) * bk is the z fourier modes of b in z @@ -345,8 +343,7 @@ FieldPerp LaplaceIPT::solve(const FieldPerp& b, const FieldPerp& x0) { kz, // wave number (different from kz only if we are taking a part // of the z-domain [and not from 0 to 2*pi]) - kz * kwaveFactor, global_flags, inner_boundary_flags, - outer_boundary_flags, &A, &C, &D); + kz * kwaveFactor, &A, &C, &D); // Patch up internal boundaries if (not localmesh->lastX()) { diff --git a/src/invert/laplace/impls/iterative_parallel_tri/iterative_parallel_tri.hxx b/src/invert/laplace/impls/iterative_parallel_tri/iterative_parallel_tri.hxx index 563ae7e61f..02e3eca06c 100644 --- a/src/invert/laplace/impls/iterative_parallel_tri/iterative_parallel_tri.hxx +++ b/src/invert/laplace/impls/iterative_parallel_tri/iterative_parallel_tri.hxx @@ -26,8 +26,8 @@ class LaplaceIPT; -#ifndef __IPT_H__ -#define __IPT_H__ +#ifndef BOUT_IPT_H +#define BOUT_IPT_H #include "bout/build_config.hxx" #include "bout/invert_laplace.hxx" @@ -234,16 +234,8 @@ private: /// First and last interior points xstart, xend int xs, xe; - - bool isGlobalFlagSet(int flag) const { return (global_flags & flag) != 0; } - bool isInnerBoundaryFlagSet(int flag) const { - return (inner_boundary_flags & flag) != 0; - } - bool isOuterBoundaryFlagSet(int flag) const { - return (outer_boundary_flags & flag) != 0; - } }; #endif // BOUT_USE_METRIC_3D -#endif // __IPT_H__ +#endif // BOUT_IPT_H diff --git a/src/invert/laplace/impls/iterative_parallel_tri/makefile b/src/invert/laplace/impls/iterative_parallel_tri/makefile deleted file mode 100644 index 78e2dac08d..0000000000 --- a/src/invert/laplace/impls/iterative_parallel_tri/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = iterative_parallel_tri.cxx -SOURCEH = iterative_parallel_tri.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/makefile b/src/invert/laplace/impls/makefile deleted file mode 100644 index 5f151c263a..0000000000 --- a/src/invert/laplace/impls/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../../.. - -DIRS = serial_tri serial_band spt petsc cyclic multigrid naulin petsc3damg iterative_parallel_tri pcr pcr_thomas hypre3d - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/multigrid/makefile b/src/invert/laplace/impls/multigrid/makefile deleted file mode 100644 index 41c049a79e..0000000000 --- a/src/invert/laplace/impls/multigrid/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = multigrid_laplace.cxx multigrid_alg.cxx multigrid_solver.cxx -SOURCEH = multigrid_laplace.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/multigrid/multigrid_alg.cxx b/src/invert/laplace/impls/multigrid/multigrid_alg.cxx index 0043c95d18..fa97a43116 100644 --- a/src/invert/laplace/impls/multigrid/multigrid_alg.cxx +++ b/src/invert/laplace/impls/multigrid/multigrid_alg.cxx @@ -104,14 +104,14 @@ void MultigridAlg::getSolution(BoutReal* x, BoutReal* b, int flag) { Array r(ldim); for (int n = 1; n < flag; n++) { residualVec(level, x, b, std::begin(r)); - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { y[i] = 0.0; } cycleMG(level, std::begin(y), std::begin(r)); - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { x[i] = x[i] + y[i]; } @@ -135,8 +135,8 @@ void MultigridAlg::cycleMG(int level, BoutReal* sol, BoutReal* rhs) { projection(level, std::begin(r), std::begin(pr)); - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < (lnx[level - 1] + 2) * (lnz[level - 1] + 2); i++) { y[i] = 0.0; } @@ -144,8 +144,8 @@ void MultigridAlg::cycleMG(int level, BoutReal* sol, BoutReal* rhs) { cycleMG(level - 1, std::begin(y), std::begin(pr)); prolongation(level - 1, std::begin(y), std::begin(iy)); - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < (lnx[level] + 2) * (lnz[level] + 2); i++) { sol[i] += iy[i]; } @@ -156,15 +156,15 @@ void MultigridAlg::cycleMG(int level, BoutReal* sol, BoutReal* rhs) { void MultigridAlg::projection(int level, BoutReal* r, BoutReal* pr) { - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < (lnx[level - 1] + 2) * (lnz[level - 1] + 2); i++) { pr[i] = 0.; } int xend = lnx[level - 1] + 1; int zend = lnz[level - 1] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int i = 1; i < xend; i++) { for (int k = 1; k < zend; k++) { int i2 = 2 * i - 1; @@ -183,16 +183,16 @@ void MultigridAlg::projection(int level, BoutReal* r, BoutReal* pr) { void MultigridAlg::prolongation(int level, BoutReal* x, BoutReal* ix) { - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < (lnx[level + 1] + 2) * (lnz[level + 1] + 2); i++) { ix[i] = 0.; } int xend = lnx[level] + 1; int zend = lnz[level] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int i = 1; i < xend; i++) { for (int k = 1; k < zend; k++) { int i2 = 2 * i - 1; @@ -219,16 +219,16 @@ void MultigridAlg::smoothings(int level, BoutReal* x, BoutReal* b) { dim = mm * (lnx[level] + 2); if (mgsm == 0) { Array x0(dim); - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) for (int num = 0; num < 2; num++) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < dim; i++) { x0[i] = x[i]; } int xend = lnx[level] + 1; int zend = lnz[level] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int i = 1; i < xend; i++) { for (int k = 1; k < zend; k++) { int nn = i * mm + k; @@ -313,8 +313,8 @@ void MultigridAlg::pGMRES(BoutReal* sol, BoutReal* rhs, int level, int iplag) { Array q(ldim); Array r(ldim); - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { sol[i] = 0.0; } @@ -335,8 +335,8 @@ void MultigridAlg::pGMRES(BoutReal* sol, BoutReal* rhs, int level, int iplag) { delete[] v; return; } - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { r[i] = 0.0; } @@ -345,8 +345,8 @@ void MultigridAlg::pGMRES(BoutReal* sol, BoutReal* rhs, int level, int iplag) { } else { cycleMG(level, std::begin(r), rhs); } - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { v[0][i] = r[i]; } @@ -360,21 +360,21 @@ void MultigridAlg::pGMRES(BoutReal* sol, BoutReal* rhs, int level, int iplag) { } a0 = 1.0 / a1; g[0] = a1; - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { v[0][i] *= a0; } - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 1; i < MAXGM + 1; i++) { g[i] = 0.0; } } for (it = 0; it < MAXGM; it++) { multiAVec(level, v[it], std::begin(q)); - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { v[it + 1][i] = 0.0; } @@ -407,8 +407,8 @@ void MultigridAlg::pGMRES(BoutReal* sol, BoutReal* rhs, int level, int iplag) { } a0 = 1.0 / a1; h[it + 1][it] = a1; - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { v[it + 1][i] *= a0; } @@ -444,13 +444,13 @@ void MultigridAlg::pGMRES(BoutReal* sol, BoutReal* rhs, int level, int iplag) { } y[i] = y[i] / h[i][i]; } - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { p[i] = sol[i]; } - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int k = 0; k < ldim; k++) { for (int i = 0; i <= it; i++) { p[k] += y[i] * v[i][k]; @@ -492,8 +492,8 @@ void MultigridAlg::pGMRES(BoutReal* sol, BoutReal* rhs, int level, int iplag) { perror = error; } /* Restart with new initial */ - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { v[0][i] = 0.0; } @@ -503,8 +503,8 @@ void MultigridAlg::pGMRES(BoutReal* sol, BoutReal* rhs, int level, int iplag) { cycleMG(level, v[0], std::begin(r)); } - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { sol[i] = p[i]; } @@ -559,11 +559,11 @@ BoutReal MultigridAlg::vectorProd(int level, BoutReal* x, BoutReal* y) { BoutReal val; BoutReal ini_e = 0.0; - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { int xend = lnx[level] + 1; int zend = lnz[level] + 1; - BOUT_OMP(for reduction(+:ini_e) collapse(2)) + BOUT_OMP_PERF(for reduction(+:ini_e) collapse(2)) for (int i = 1; i < xend; i++) { for (int k = 1; k < zend; k++) { int ii = i * (lnz[level] + 2) + k; @@ -583,16 +583,16 @@ BoutReal MultigridAlg::vectorProd(int level, BoutReal* x, BoutReal* y) { void MultigridAlg::multiAVec(int level, BoutReal* x, BoutReal* b) { int mm = lnz[level] + 2; - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < mm * (lnx[level] + 2); i++) { b[i] = 0.0; } int xend = lnx[level] + 1; int zend = lnz[level] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int i = 1; i < xend; i++) { for (int k = 1; k < zend; k++) { int nn = i * mm + k; @@ -614,16 +614,16 @@ void MultigridAlg::residualVec(int level, BoutReal* x, BoutReal* b, BoutReal* r) int mm; mm = lnz[level] + 2; - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < mm * (lnx[level] + 2); i++) { r[i] = 0.0; } int xend = lnx[level] + 1; int zend = lnz[level] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int i = 1; i < xend; i++) { for (int k = 1; k < zend; k++) { int nn = i * mm + k; @@ -646,16 +646,16 @@ void MultigridAlg::setMatrixC(int level) { BoutReal ratio = 8.0; - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < (lnx[level - 1] + 2) * (lnz[level - 1] + 2) * 9; i++) { matmg[level - 1][i] = 0.0; } int xend = lnx[level - 1] + 1; int zend = lnz[level - 1] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int i = 1; i < xend; i++) { for (int k = 1; k < zend; k++) { int i2 = 2 * i - 1; @@ -704,7 +704,7 @@ void MultigridAlg::communications(BoutReal* x, int level) { MPI_Status status[4]; int stag, rtag; - MAYBE_UNUSED(int ierr); + [[maybe_unused]] int ierr; if (zNP > 1) { MPI_Request requests[] = {MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, @@ -809,8 +809,8 @@ void MultigridAlg::solveMG(BoutReal* sol, BoutReal* rhs, int level) { BoutReal ini_e, perror, error, rederr; int ldim = (lnx[level] + 2) * (lnz[level] + 2); - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { sol[i] = 0.0; } @@ -825,22 +825,22 @@ void MultigridAlg::solveMG(BoutReal* sol, BoutReal* rhs, int level) { } Array y(ldim); Array r(ldim); - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { r[i] = rhs[i]; } perror = ini_e; for (m = 0; m < MAXIT; m++) { - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { y[i] = 0.0; } cycleMG(level, std::begin(y), std::begin(r)); - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < ldim; i++) { sol[i] = sol[i] + y[i]; } diff --git a/src/invert/laplace/impls/multigrid/multigrid_laplace.cxx b/src/invert/laplace/impls/multigrid/multigrid_laplace.cxx index beb9262ed8..c5076cd499 100644 --- a/src/invert/laplace/impls/multigrid/multigrid_laplace.cxx +++ b/src/invert/laplace/impls/multigrid/multigrid_laplace.cxx @@ -67,7 +67,6 @@ LaplaceMultigrid::LaplaceMultigrid(Options* opt, const CELL_LOC loc, Mesh* mesh_ opts->get("atol", atol, pow(10.0, -20), true); opts->get("dtol", dtol, pow(10.0, 5), true); opts->get("smtype", mgsm, 1, true); -#if BOUT_USE_OPENMP if (mgsm != 0 && omp_get_max_threads() > 1) { output_warn << "WARNING: in multigrid Laplace solver, for smtype!=0 the smoothing " "cannot be parallelised with OpenMP threads." @@ -75,7 +74,6 @@ LaplaceMultigrid::LaplaceMultigrid(Options* opt, const CELL_LOC loc, Mesh* mesh_ << " Consider using smtype=0 instead when using OpenMP threads." << endl; } -#endif opts->get("jacomega", omega, 0.8, true); opts->get("solvertype", mgplag, 1, true); opts->get("cftype", cftype, 0, true); @@ -86,19 +84,18 @@ LaplaceMultigrid::LaplaceMultigrid(Options* opt, const CELL_LOC loc, Mesh* mesh_ // Initialize, allocate memory, etc. comms_tagbase = 385; // Some random number - int implemented_global_flags = INVERT_START_NEW; - if (global_flags & ~implemented_global_flags) { + constexpr int implemented_global_flags = INVERT_START_NEW; + if (isGlobalFlagSet(~implemented_global_flags)) { throw BoutException("Attempted to set Laplacian inversion flag that is not " "implemented in LaplaceMultigrid."); } - int implemented_boundary_flags = - INVERT_AC_GRAD + INVERT_SET - + INVERT_DC_GRAD; // INVERT_DC_GRAD does not actually do anything, but harmless to set while comparing to Fourier solver with Neumann boundary conditions - if (inner_boundary_flags & ~implemented_boundary_flags) { + // INVERT_DC_GRAD does not actually do anything, but harmless to set while comparing to Fourier solver with Neumann boundary conditions + constexpr int implemented_boundary_flags = INVERT_AC_GRAD + INVERT_SET + INVERT_DC_GRAD; + if (isInnerBoundaryFlagSet(~implemented_boundary_flags)) { throw BoutException("Attempted to set Laplacian inner boundary inversion flag that " "is not implemented in LaplaceMultigrid."); } - if (outer_boundary_flags & ~implemented_boundary_flags) { + if (isOuterBoundaryFlagSet(~implemented_boundary_flags)) { throw BoutException("Attempted to set Laplacian outer boundary inversion flag that " "is not implemented in LaplaceMultigrid."); } @@ -218,11 +215,9 @@ LaplaceMultigrid::LaplaceMultigrid(Options* opt, const CELL_LOC loc, Mesh* mesh_ } else { output << "Multigrid solver with merging " << mgmpi << endl; } -#if BOUT_USE_OPENMP - BOUT_OMP(parallel) - BOUT_OMP(master) + BOUT_OMP_SAFE(parallel) + BOUT_OMP_SAFE(master) { output << "Num threads = " << omp_get_num_threads() << endl; } -#endif } } @@ -246,10 +241,10 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { int lz2 = lzz + 2; int lxx = kMG->lnx[level]; - if (global_flags & INVERT_START_NEW) { + if (isGlobalFlagSet(INVERT_START_NEW)) { // set initial guess to zero - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for collapse(2)) for (int i = 1; i < lxx + 1; i++) { for (int k = 1; k < lzz + 1; k++) { x[i * lz2 + k] = 0.; @@ -257,8 +252,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } else { // Read initial guess into local array, ignoring guard cells - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for collapse(2)) for (int i = 1; i < lxx + 1; i++) { for (int k = 1; k < lzz + 1; k++) { int i2 = i - 1 + localmesh->xstart; @@ -269,8 +264,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } // Read RHS into local array - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for collapse(2)) for (int i = 1; i < lxx + 1; i++) { for (int k = 1; k < lzz + 1; k++) { int i2 = i - 1 + localmesh->xstart; @@ -280,12 +275,12 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } if (localmesh->firstX()) { - if (inner_boundary_flags & INVERT_AC_GRAD) { + if (isInnerBoundaryFlagSet(INVERT_AC_GRAD)) { // Neumann boundary condition - if (inner_boundary_flags & INVERT_SET) { + if (isInnerBoundaryFlagSet(INVERT_SET)) { // guard cells of x0 specify gradient to set at inner boundary - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; x[k] = -x0(localmesh->xstart - 1, k2) @@ -294,8 +289,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } else { // zero gradient inner boundary condition - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { // set inner guard cells x[k] = 0.0; @@ -303,10 +298,10 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } else { // Dirichlet boundary condition - if (inner_boundary_flags & INVERT_SET) { + if (isInnerBoundaryFlagSet(INVERT_SET)) { // guard cells of x0 specify value to set at inner boundary - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; x[k] = 2. * x0(localmesh->xstart - 1, k2); @@ -314,8 +309,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } else { // zero value inner boundary condition - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { // set inner guard cells x[k] = 0.; @@ -324,12 +319,12 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } if (localmesh->lastX()) { - if (outer_boundary_flags & INVERT_AC_GRAD) { + if (isOuterBoundaryFlagSet(INVERT_AC_GRAD)) { // Neumann boundary condition - if (inner_boundary_flags & INVERT_SET) { + if (isInnerBoundaryFlagSet(INVERT_SET)) { // guard cells of x0 specify gradient to set at outer boundary - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; x[(lxx + 1) * lz2 + k] = x0(localmesh->xend + 1, k2) @@ -339,8 +334,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } else { // zero gradient outer boundary condition - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { // set outer guard cells x[(lxx + 1) * lz2 + k] = 0.; @@ -348,10 +343,10 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } else { // Dirichlet boundary condition - if (outer_boundary_flags & INVERT_SET) { + if (isOuterBoundaryFlagSet(INVERT_SET)) { // guard cells of x0 specify value to set at outer boundary - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; x[(lxx + 1) * lz2 + k] = 2. * x0(localmesh->xend + 1, k2); @@ -359,8 +354,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } else { // zero value inner boundary condition - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { // set outer guard cells x[(lxx + 1) * lz2 + k] = 0.; @@ -370,8 +365,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } // Exchange ghost cells of initial guess - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < lxx + 2; i++) { x[i * lz2] = x[(i + 1) * lz2 - 2]; x[(i + 1) * lz2 - 1] = x[i * lz2 + 1]; @@ -471,8 +466,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { #endif // Copy solution into a FieldPerp to return - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for collapse(2)) for (int i = 1; i < lxx + 1; i++) { for (int k = 1; k < lzz + 1; k++) { int i2 = i - 1 + localmesh->xstart; @@ -481,13 +476,13 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } if (localmesh->firstX()) { - if (inner_boundary_flags & INVERT_AC_GRAD) { + if (isInnerBoundaryFlagSet(INVERT_AC_GRAD)) { // Neumann boundary condition - if (inner_boundary_flags & INVERT_SET) { + if (isInnerBoundaryFlagSet(INVERT_SET)) { // guard cells of x0 specify gradient to set at inner boundary int i2 = -1 + localmesh->xstart; - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; result(i2, k2) = x[lz2 + k] @@ -498,8 +493,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } else { // zero gradient inner boundary condition int i2 = -1 + localmesh->xstart; - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; result(i2, k2) = x[lz2 + k]; @@ -507,11 +502,11 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } else { // Dirichlet boundary condition - if (inner_boundary_flags & INVERT_SET) { + if (isInnerBoundaryFlagSet(INVERT_SET)) { // guard cells of x0 specify value to set at inner boundary int i2 = -1 + localmesh->xstart; - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; result(i2, k2) = 2. * x0(localmesh->xstart - 1, k2) - x[lz2 + k]; @@ -519,8 +514,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } else { // zero value inner boundary condition int i2 = -1 + localmesh->xstart; - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; result(i2, k2) = -x[lz2 + k]; @@ -529,13 +524,13 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } if (localmesh->lastX()) { - if (outer_boundary_flags & INVERT_AC_GRAD) { + if (isOuterBoundaryFlagSet(INVERT_AC_GRAD)) { // Neumann boundary condition - if (inner_boundary_flags & INVERT_SET) { + if (isInnerBoundaryFlagSet(INVERT_SET)) { // guard cells of x0 specify gradient to set at outer boundary int i2 = lxx + localmesh->xstart; - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; result(i2, k2) = x[lxx * lz2 + k] @@ -546,8 +541,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } else { // zero gradient outer boundary condition int i2 = lxx + localmesh->xstart; - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; result(i2, k2) = x[lxx * lz2 + k]; @@ -555,11 +550,11 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } } else { // Dirichlet boundary condition - if (outer_boundary_flags & INVERT_SET) { + if (isOuterBoundaryFlagSet(INVERT_SET)) { // guard cells of x0 specify value to set at outer boundary int i2 = lxx + localmesh->xstart; - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; result(i2, k2) = 2. * x0(localmesh->xend + 1, k2) - x[lxx * lz2 + k]; @@ -567,8 +562,8 @@ FieldPerp LaplaceMultigrid::solve(const FieldPerp& b_in, const FieldPerp& x0) { } else { // zero value inner boundary condition int i2 = lxx + localmesh->xstart; - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < lzz + 1; k++) { int k2 = k - 1; result(i2, k2) = -x[lxx * lz2 + k]; @@ -592,8 +587,8 @@ void LaplaceMultigrid::generateMatrixF(int level) { int llx = kMG->lnx[level]; int llz = kMG->lnz[level]; - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for collapse(2)) for (int i = 1; i < llx + 1; i++) { for (int k = 1; k < llz + 1; k++) { int i2 = i - 1 + localmesh->xstart; @@ -655,10 +650,10 @@ void LaplaceMultigrid::generateMatrixF(int level) { // Here put boundary conditions if (kMG->rProcI == 0) { - if (inner_boundary_flags & INVERT_AC_GRAD) { + if (isInnerBoundaryFlagSet(INVERT_AC_GRAD)) { // Neumann boundary condition - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < llz + 1; k++) { int ic = llz + 2 + k; mat[ic * 9 + 3] += mat[ic * 9]; @@ -673,8 +668,8 @@ void LaplaceMultigrid::generateMatrixF(int level) { } } else { // Dirichlet boundary condition - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < llz + 1; k++) { int ic = llz + 2 + k; mat[ic * 9 + 3] -= mat[ic * 9]; @@ -690,10 +685,10 @@ void LaplaceMultigrid::generateMatrixF(int level) { } } if (kMG->rProcI == kMG->xNP - 1) { - if (outer_boundary_flags & INVERT_AC_GRAD) { + if (isOuterBoundaryFlagSet(INVERT_AC_GRAD)) { // Neumann boundary condition - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < llz + 1; k++) { int ic = llx * (llz + 2) + k; mat[ic * 9 + 3] += mat[ic * 9 + 6]; @@ -708,8 +703,8 @@ void LaplaceMultigrid::generateMatrixF(int level) { } } else { // Dirichlet boundary condition - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int k = 1; k < llz + 1; k++) { int ic = llx * (llz + 2) + k; mat[ic * 9 + 3] -= mat[ic * 9 + 6]; diff --git a/src/invert/laplace/impls/multigrid/multigrid_laplace.hxx b/src/invert/laplace/impls/multigrid/multigrid_laplace.hxx index 4186147874..f0b3cfc5c1 100644 --- a/src/invert/laplace/impls/multigrid/multigrid_laplace.hxx +++ b/src/invert/laplace/impls/multigrid/multigrid_laplace.hxx @@ -28,8 +28,8 @@ * **************************************************************************/ -#ifndef __MULTIGRID_LAPLACE_H__ -#define __MULTIGRID_LAPLACE_H__ +#ifndef BOUT_MULTIGRID_LAPLACE_H +#define BOUT_MULTIGRID_LAPLACE_H #include "bout/build_config.hxx" #include "bout/invert_laplace.hxx" @@ -246,4 +246,4 @@ RegisterLaplace registerlaplacemultigrid(LAPLACE_MULTIGRID); #endif // BOUT_USE_METRIC_3D -#endif // __MULTIGRID_LAPLACE_H__ +#endif // BOUT_MULTIGRID_LAPLACE_H diff --git a/src/invert/laplace/impls/multigrid/multigrid_solver.cxx b/src/invert/laplace/impls/multigrid/multigrid_solver.cxx index 6d448e4db7..0c5ad82d6c 100644 --- a/src/invert/laplace/impls/multigrid/multigrid_solver.cxx +++ b/src/invert/laplace/impls/multigrid/multigrid_solver.cxx @@ -290,15 +290,15 @@ void Multigrid1DP::lowestSolver(BoutReal* x, BoutReal* b, int UNUSED(plag)) { int nx = (xProcI % rMG->zNP) * lnx[0]; - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < dim; i++) { y[i] = 0.0; r[i] = 0.0; } - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < dimg; i++) { yl[i] = 0.0; yg[i] = 0.0; @@ -306,7 +306,7 @@ void Multigrid1DP::lowestSolver(BoutReal* x, BoutReal* b, int UNUSED(plag)) { int xend = lnx[0] + 1; int zend = lnz[0] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = (nx + ix) * (lnz[0] + 2) + iz; @@ -319,11 +319,11 @@ void Multigrid1DP::lowestSolver(BoutReal* x, BoutReal* b, int UNUSED(plag)) { MPI_SUM, comm2D); int nz = (xProcI % rMG->zNP) * (rMG->lnz[level]); - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { int xend = rMG->lnx[level] + 1; int zend = rMG->lnz[level] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = ix * (lnz[0] + 2) + nz + iz; @@ -335,9 +335,9 @@ void Multigrid1DP::lowestSolver(BoutReal* x, BoutReal* b, int UNUSED(plag)) { rMG->getSolution(std::begin(y), std::begin(r), 1); - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < dimg; i++) { yl[i] = 0.0; yg[i] = 0.0; @@ -345,7 +345,7 @@ void Multigrid1DP::lowestSolver(BoutReal* x, BoutReal* b, int UNUSED(plag)) { int xend = rMG->lnx[level] + 1; int zend = rMG->lnz[level] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = ix * (lnz[0] + 2) + nz + iz; @@ -357,11 +357,11 @@ void Multigrid1DP::lowestSolver(BoutReal* x, BoutReal* b, int UNUSED(plag)) { bout::globals::mpi->MPI_Allreduce(std::begin(yl), std::begin(yg), dimg, MPI_DOUBLE, MPI_SUM, comm2D); - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { int xend = lnx[0] + 1; int zend = lnz[0] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = (nx + ix) * (lnz[0] + 2) + iz; @@ -377,16 +377,16 @@ void Multigrid1DP::lowestSolver(BoutReal* x, BoutReal* b, int UNUSED(plag)) { Array y(dim); Array r(dim); int nx = xProcI * lnx[0]; - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < dim; i++) { y[i] = 0.0; r[i] = 0.0; } int xend = lnx[0] + 1; int zend = lnz[0] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = (nx + ix) * (lnz[0] + 2) + iz; @@ -397,18 +397,18 @@ void Multigrid1DP::lowestSolver(BoutReal* x, BoutReal* b, int UNUSED(plag)) { } bout::globals::mpi->MPI_Allreduce(std::begin(y), std::begin(r), dim, MPI_DOUBLE, MPI_SUM, commMG); - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < dim; i++) { y[i] = 0.0; } sMG->getSolution(std::begin(y), std::begin(r), 1); - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { int xend = lnx[0] + 1; int zend = lnz[0] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = (nx + ix) * (lnz[0] + 2) + iz; @@ -430,21 +430,21 @@ void Multigrid1DP::convertMatrixF2D(int level) { Array yl(dim * 9); Array yg(dim * 9); int nx = (xProcI % rMG->zNP) * lnx[0]; - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < dim * 9; i++) { yl[i] = 0.0; yg[i] = 0.0; } - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < (rMG->lnx[level] + 2) * (rMG->lnz[level] + 2) * 9; i++) { rMG->matmg[level][i] = 0.0; } int xend = lnx[0] + 1; int zend = lnz[0] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = (nx + ix) * (lnz[0] + 2) + iz; @@ -494,11 +494,11 @@ void Multigrid1DP::convertMatrixF2D(int level) { } int nz = (xProcI % rMG->zNP) * (rMG->lnz[level]); - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { int xend = rMG->lnx[level] + 1; int zend = rMG->lnz[level] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = ix * (lnz[0] + 2) + nz + iz; @@ -517,16 +517,16 @@ void Multigrid1DP::convertMatrixFS(int level) { Array yl(dim * 9); BoutReal* yg = sMG->matmg[level]; int nx = xProcI * lnx[0]; - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < dim * 9; i++) { yl[i] = 0.0; yg[i] = 0.0; } int xend = lnx[0] + 1; int zend = lnz[0] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = (nx + ix) * (lnz[0] + 2) + iz; @@ -675,9 +675,9 @@ void Multigrid2DPf1D::lowestSolver(BoutReal* x, BoutReal* b, int UNUSED(plag)) { Array r(dim); int nx = xProcI * lnx[0]; int nz = zProcI * lnz[0]; - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < dim; i++) { y[i] = 0.0; r[i] = 0.0; @@ -685,7 +685,7 @@ void Multigrid2DPf1D::lowestSolver(BoutReal* x, BoutReal* b, int UNUSED(plag)) { int xend = lnx[0] + 1; int zend = lnz[0] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = (nx + ix) * (gnz[0] + 2) + nz + iz; @@ -696,17 +696,17 @@ void Multigrid2DPf1D::lowestSolver(BoutReal* x, BoutReal* b, int UNUSED(plag)) { } bout::globals::mpi->MPI_Allreduce(std::begin(y), std::begin(r), dim, MPI_DOUBLE, MPI_SUM, commMG); - BOUT_OMP(parallel default(shared)) - BOUT_OMP(for) + BOUT_OMP_PERF(parallel default(shared)) + BOUT_OMP_PERF(for) for (int i = 0; i < dim; i++) { y[i] = 0.0; } sMG->getSolution(std::begin(y), std::begin(r), 1); - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { int xend = lnx[0] + 1; int zend = lnz[0] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = (nx + ix) * (gnz[0] + 2) + nz + iz; @@ -728,16 +728,16 @@ void Multigrid2DPf1D::convertMatrixFS(int level) { BoutReal* yg = sMG->matmg[level]; int nx = xProcI * lnx[0]; int nz = zProcI * lnz[0]; - BOUT_OMP(parallel default(shared)) + BOUT_OMP_PERF(parallel default(shared)) { - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int i = 0; i < dim * 9; i++) { yl[i] = 0.0; yg[i] = 0.0; } int xend = lnx[0] + 1; int zend = lnz[0] + 1; - BOUT_OMP(for collapse(2)) + BOUT_OMP_PERF(for collapse(2)) for (int ix = 1; ix < xend; ix++) { for (int iz = 1; iz < zend; iz++) { int nn = (nx + ix) * (gnz[0] + 2) + nz + iz; diff --git a/src/invert/laplace/impls/naulin/makefile b/src/invert/laplace/impls/naulin/makefile deleted file mode 100644 index 6ce4495e8e..0000000000 --- a/src/invert/laplace/impls/naulin/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = naulin_laplace.cxx -SOURCEH = naulin_laplace.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/naulin/naulin_laplace.cxx b/src/invert/laplace/impls/naulin/naulin_laplace.cxx index d82f874cbb..e315d3c771 100644 --- a/src/invert/laplace/impls/naulin/naulin_laplace.cxx +++ b/src/invert/laplace/impls/naulin/naulin_laplace.cxx @@ -174,9 +174,9 @@ LaplaceNaulin::LaplaceNaulin(Options* opt, const CELL_LOC loc, Mesh* mesh_in, // invert Delp2 and we will not converge ASSERT0(delp2type == "cyclic" || delp2type == "spt" || delp2type == "tri"); // Use same flags for FFT solver as for NaulinSolver - delp2solver->setGlobalFlags(global_flags); - delp2solver->setInnerBoundaryFlags(inner_boundary_flags); - delp2solver->setOuterBoundaryFlags(outer_boundary_flags); + delp2solver->setGlobalFlags(getGlobalFlags()); + delp2solver->setInnerBoundaryFlags(getInnerBoundaryFlags()); + delp2solver->setOuterBoundaryFlags(getOuterBoundaryFlags()); static int naulinsolver_count = 1; setPerformanceName(fmt::format("{}{}", "naulinsolver", ++naulinsolver_count)); @@ -258,7 +258,7 @@ Field3D LaplaceNaulin::solve(const Field3D& rhs, const Field3D& x0) { // Note take a copy of the 'b' argument, because we want to return a copy of it in the // result - if ((inner_boundary_flags & INVERT_SET) || (outer_boundary_flags & INVERT_SET)) { + if (isInnerBoundaryFlagSet(INVERT_SET) || isOuterBoundaryFlagSet(INVERT_SET)) { // This passes in the boundary conditions from x0's guard cells copy_x_boundaries(x_guess, x0, localmesh); } diff --git a/src/invert/laplace/impls/naulin/naulin_laplace.hxx b/src/invert/laplace/impls/naulin/naulin_laplace.hxx index f544e74336..e464ef18e7 100644 --- a/src/invert/laplace/impls/naulin/naulin_laplace.hxx +++ b/src/invert/laplace/impls/naulin/naulin_laplace.hxx @@ -25,8 +25,8 @@ class LaplaceNaulin; -#ifndef __LAP_NAULIN_H__ -#define __LAP_NAULIN_H__ +#ifndef BOUT_LAP_NAULIN_H +#define BOUT_LAP_NAULIN_H #include #include @@ -179,4 +179,4 @@ private: void copy_x_boundaries(Field3D& x, const Field3D& x0, Mesh* mesh); }; -#endif // __LAP_NAULIN_H__ +#endif // BOUT_LAP_NAULIN_H diff --git a/src/invert/laplace/impls/pcr/makefile b/src/invert/laplace/impls/pcr/makefile deleted file mode 100644 index c15f57aea5..0000000000 --- a/src/invert/laplace/impls/pcr/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = pcr.cxx -SOURCEH = pcr.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/pcr/pcr.cxx b/src/invert/laplace/impls/pcr/pcr.cxx index 9402ba9f1b..48bbdbac4b 100644 --- a/src/invert/laplace/impls/pcr/pcr.cxx +++ b/src/invert/laplace/impls/pcr/pcr.cxx @@ -149,19 +149,19 @@ FieldPerp LaplacePCR::solve(const FieldPerp& rhs, const FieldPerp& x0) { // If the flags to assign that only one guard cell should be used is set inbndry = localmesh->xstart; outbndry = localmesh->xstart; - if (((global_flags & INVERT_BOTH_BNDRY_ONE) != 0) || (localmesh->xstart < 2)) { + if (isGlobalFlagSet(INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { inbndry = outbndry = 1; } - if ((inner_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isInnerBoundaryFlagSet(INVERT_BNDRY_ONE)) { inbndry = 1; } - if ((outer_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isOuterBoundaryFlagSet(INVERT_BNDRY_ONE)) { outbndry = 1; } if (dst) { const BoutReal zlen = getUniform(coords->dz) * (localmesh->LocalNz - 3); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array( @@ -169,14 +169,13 @@ FieldPerp LaplacePCR::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Loop over X indices, including boundaries but not guard cells. (unless periodic // in x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ix = xs; ix <= xe; ix++) { // Take DST in Z direction and put result in k1d - if (((ix < inbndry) && ((inner_boundary_flags & INVERT_SET) != 0) - && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && ((outer_boundary_flags & INVERT_SET) != 0) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary DST(x0[ix] + 1, localmesh->LocalNz - 2, std::begin(k1d)); } else { @@ -191,7 +190,7 @@ FieldPerp LaplacePCR::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Get elements of the tridiagonal matrix // including boundary conditions - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int kz = 0; kz < nmode; kz++) { BoutReal kwave = kz * 2.0 * PI / (2. * zlen); // wave number is 1/[rad]; DST has extra 2. @@ -199,23 +198,22 @@ FieldPerp LaplacePCR::solve(const FieldPerp& rhs, const FieldPerp& x0) { tridagMatrix(&a(kz, 0), &b(kz, 0), &c(kz, 0), &bcmplx(kz, 0), jy, kz, // wave number index kwave, // kwave (inverse wave length) - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false); // Don't include guard cells in arrays } - } // BOUT_OMP(parallel) + } // BOUT_OMP_PERF(parallel) // Solve tridiagonal systems cr_pcr_solver(a, b, c, bcmplx, xcmplx); // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array( localmesh->LocalNz); // ZFFT routine expects input of this length - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ix = xs; ix <= xe; ix++) { for (int kz = 0; kz < nmode; kz++) { k1d[kz] = xcmplx(kz, ix - xs); @@ -233,7 +231,7 @@ FieldPerp LaplacePCR::solve(const FieldPerp& rhs, const FieldPerp& x0) { } } else { const BoutReal zlength = getUniform(coords->zlength()); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array((localmesh->LocalNz) / 2 @@ -241,14 +239,13 @@ FieldPerp LaplacePCR::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Loop over X indices, including boundaries but not guard cells (unless periodic in // x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ix = xs; ix <= xe; ix++) { // Take FFT in Z direction, apply shift, and put result in k1d - if (((ix < inbndry) && ((inner_boundary_flags & INVERT_SET) != 0) - && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && ((outer_boundary_flags & INVERT_SET) != 0) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary rfft(x0[ix], localmesh->LocalNz, std::begin(k1d)); } else { @@ -263,31 +260,30 @@ FieldPerp LaplacePCR::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Get elements of the tridiagonal matrix // including boundary conditions - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int kz = 0; kz < nmode; kz++) { BoutReal kwave = kz * 2.0 * PI / zlength; // wave number is 1/[rad] tridagMatrix(&a(kz, 0), &b(kz, 0), &c(kz, 0), &bcmplx(kz, 0), jy, kz, // True for the component constant (DC) in Z kwave, // Z wave number - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false); // Don't include guard cells in arrays } - } // BOUT_OMP(parallel) + } // BOUT_OMP_PERF(parallel) // Solve tridiagonal systems cr_pcr_solver(a, b, c, bcmplx, xcmplx); // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array((localmesh->LocalNz) / 2 + 1); // ZFFT routine expects input of this length - const bool zero_DC = (global_flags & INVERT_ZERO_DC) != 0; + const bool zero_DC = isGlobalFlagSet(INVERT_ZERO_DC); - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ix = xs; ix <= xe; ix++) { if (zero_DC) { k1d[0] = 0.; @@ -327,13 +323,13 @@ Field3D LaplacePCR::solve(const Field3D& rhs, const Field3D& x0) { // If the flags to assign that only one guard cell should be used is set inbndry = localmesh->xstart; outbndry = localmesh->xstart; - if (((global_flags & INVERT_BOTH_BNDRY_ONE) != 0) || (localmesh->xstart < 2)) { + if (isGlobalFlagSet(INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { inbndry = outbndry = 1; } - if ((inner_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isInnerBoundaryFlagSet(INVERT_BNDRY_ONE)) { inbndry = 1; } - if ((outer_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isOuterBoundaryFlagSet(INVERT_BNDRY_ONE)) { outbndry = 1; } @@ -371,7 +367,7 @@ Field3D LaplacePCR::solve(const Field3D& rhs, const Field3D& x0) { if (dst) { const BoutReal zlen = getUniform(coords->dz) * (localmesh->LocalNz - 3); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array( @@ -379,7 +375,7 @@ Field3D LaplacePCR::solve(const Field3D& rhs, const Field3D& x0) { // Loop over X and Y indices, including boundaries but not guard cells. // (unless periodic in x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ind = 0; ind < nxny; ++ind) { // ind = (ix - xs)*(ye - ys + 1) + (iy - ys) int ix = xs + ind / ny; @@ -387,10 +383,9 @@ Field3D LaplacePCR::solve(const Field3D& rhs, const Field3D& x0) { // Take DST in Z direction and put result in k1d - if (((ix < inbndry) && ((inner_boundary_flags & INVERT_SET) != 0) - && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && ((outer_boundary_flags & INVERT_SET) != 0) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary DST(x0(ix, iy) + 1, localmesh->LocalNz - 2, std::begin(k1d)); } else { @@ -405,7 +400,7 @@ Field3D LaplacePCR::solve(const Field3D& rhs, const Field3D& x0) { // Get elements of the tridiagonal matrix // including boundary conditions - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nsys; ind++) { // ind = (iy - ys) * nmode + kz int iy = ys + ind / nmode; @@ -417,23 +412,22 @@ Field3D LaplacePCR::solve(const Field3D& rhs, const Field3D& x0) { tridagMatrix(&a3D(ind, 0), &b3D(ind, 0), &c3D(ind, 0), &bcmplx3D(ind, 0), iy, kz, // wave number index kwave, // kwave (inverse wave length) - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false); // Don't include guard cells in arrays } - } // BOUT_OMP(parallel) + } // BOUT_OMP_PERF(parallel) // Solve tridiagonal systems cr_pcr_solver(a3D, b3D, c3D, bcmplx3D, xcmplx3D); // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array( localmesh->LocalNz); // ZFFT routine expects input of this length - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nxny; ++ind) { // Loop over X and Y // ind = (ix - xs)*(ye - ys + 1) + (iy - ys) int ix = xs + ind / ny; @@ -455,7 +449,7 @@ Field3D LaplacePCR::solve(const Field3D& rhs, const Field3D& x0) { } } else { const BoutReal zlength = getUniform(coords->zlength()); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array(localmesh->LocalNz / 2 @@ -464,7 +458,7 @@ Field3D LaplacePCR::solve(const Field3D& rhs, const Field3D& x0) { // Loop over X and Y indices, including boundaries but not guard cells // (unless periodic in x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ind = 0; ind < nxny; ++ind) { // ind = (ix - xs)*(ye - ys + 1) + (iy - ys) int ix = xs + ind / ny; @@ -472,10 +466,9 @@ Field3D LaplacePCR::solve(const Field3D& rhs, const Field3D& x0) { // Take FFT in Z direction, apply shift, and put result in k1d - if (((ix < inbndry) && ((inner_boundary_flags & INVERT_SET) != 0) - && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && ((outer_boundary_flags & INVERT_SET) != 0) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary rfft(x0(ix, iy), localmesh->LocalNz, std::begin(k1d)); } else { @@ -490,7 +483,7 @@ Field3D LaplacePCR::solve(const Field3D& rhs, const Field3D& x0) { // Get elements of the tridiagonal matrix // including boundary conditions - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nsys; ind++) { // ind = (iy - ys) * nmode + kz int iy = ys + ind / nmode; @@ -500,25 +493,24 @@ Field3D LaplacePCR::solve(const Field3D& rhs, const Field3D& x0) { tridagMatrix(&a3D(ind, 0), &b3D(ind, 0), &c3D(ind, 0), &bcmplx3D(ind, 0), iy, kz, // True for the component constant (DC) in Z kwave, // Z wave number - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false); // Don't include guard cells in arrays } - } // BOUT_OMP(parallel) + } // BOUT_OMP_PERF(parallel) // Solve tridiagonal systems cr_pcr_solver(a3D, b3D, c3D, bcmplx3D, xcmplx3D); // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array((localmesh->LocalNz) / 2 + 1); // ZFFT routine expects input of this length - const bool zero_DC = (global_flags & INVERT_ZERO_DC) != 0; + const bool zero_DC = isGlobalFlagSet(INVERT_ZERO_DC); - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nxny; ++ind) { // Loop over X and Y int ix = xs + ind / ny; int iy = ys + ind % ny; diff --git a/src/invert/laplace/impls/pcr/pcr.hxx b/src/invert/laplace/impls/pcr/pcr.hxx index 38b7c356d3..ec4637f56c 100644 --- a/src/invert/laplace/impls/pcr/pcr.hxx +++ b/src/invert/laplace/impls/pcr/pcr.hxx @@ -172,14 +172,6 @@ private: /// First and last interior points xstart, xend int xs, xe; - bool isGlobalFlagSet(int flag) const { return (global_flags & flag) != 0; } - bool isInnerBoundaryFlagSet(int flag) const { - return (inner_boundary_flags & flag) != 0; - } - bool isOuterBoundaryFlagSet(int flag) const { - return (outer_boundary_flags & flag) != 0; - } - bool dst{false}; }; diff --git a/src/invert/laplace/impls/pcr_thomas/makefile b/src/invert/laplace/impls/pcr_thomas/makefile deleted file mode 100644 index 6370a5bd5e..0000000000 --- a/src/invert/laplace/impls/pcr_thomas/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = pcr_thomas.cxx -SOURCEH = pcr_thomas.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/pcr_thomas/pcr_thomas.cxx b/src/invert/laplace/impls/pcr_thomas/pcr_thomas.cxx index 925fb842ce..61c8f58694 100644 --- a/src/invert/laplace/impls/pcr_thomas/pcr_thomas.cxx +++ b/src/invert/laplace/impls/pcr_thomas/pcr_thomas.cxx @@ -145,19 +145,19 @@ FieldPerp LaplacePCR_THOMAS::solve(const FieldPerp& rhs, const FieldPerp& x0) { // If the flags to assign that only one guard cell should be used is set int inbndry = localmesh->xstart; int outbndry = localmesh->xstart; - if (((global_flags & INVERT_BOTH_BNDRY_ONE) != 0) || (localmesh->xstart < 2)) { + if (isGlobalFlagSet(INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { inbndry = outbndry = 1; } - if ((inner_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isInnerBoundaryFlagSet(INVERT_BNDRY_ONE)) { inbndry = 1; } - if ((outer_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isOuterBoundaryFlagSet(INVERT_BNDRY_ONE)) { outbndry = 1; } if (dst) { const BoutReal zlength = getUniform(coords->dz) * (localmesh->LocalNz - 3); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array( @@ -165,14 +165,13 @@ FieldPerp LaplacePCR_THOMAS::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Loop over X indices, including boundaries but not guard cells. (unless periodic // in x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ix = xs; ix <= xe; ix++) { // Take DST in Z direction and put result in k1d - if (((ix < inbndry) && ((inner_boundary_flags & INVERT_SET) != 0) - && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && ((outer_boundary_flags & INVERT_SET) != 0) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary DST(x0[ix] + 1, localmesh->LocalNz - 2, std::begin(k1d)); } else { @@ -187,7 +186,7 @@ FieldPerp LaplacePCR_THOMAS::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Get elements of the tridiagonal matrix // including boundary conditions - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int kz = 0; kz < nmode; kz++) { // wave number is 1/[rad]; DST has extra 2. const BoutReal kwave = kz * 2.0 * PI / (2. * zlength); @@ -195,8 +194,7 @@ FieldPerp LaplacePCR_THOMAS::solve(const FieldPerp& rhs, const FieldPerp& x0) { tridagMatrix(&a(kz, 0), &b(kz, 0), &c(kz, 0), &bcmplx(kz, 0), jy, kz, // wave number index kwave, // kwave (inverse wave length) - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false); // Don't include guard cells in arrays } } @@ -205,13 +203,13 @@ FieldPerp LaplacePCR_THOMAS::solve(const FieldPerp& rhs, const FieldPerp& x0) { pcr_thomas_solver(a, b, c, bcmplx, xcmplx); // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array( localmesh->LocalNz); // ZFFT routine expects input of this length - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ix = xs; ix <= xe; ix++) { for (int kz = 0; kz < nmode; kz++) { k1d[kz] = xcmplx(kz, ix - xs); @@ -229,7 +227,7 @@ FieldPerp LaplacePCR_THOMAS::solve(const FieldPerp& rhs, const FieldPerp& x0) { } } else { const BoutReal zlength = getUniform(coords->zlength()); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array((localmesh->LocalNz) / 2 @@ -237,14 +235,13 @@ FieldPerp LaplacePCR_THOMAS::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Loop over X indices, including boundaries but not guard cells (unless periodic in // x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ix = xs; ix <= xe; ix++) { // Take FFT in Z direction, apply shift, and put result in k1d - if (((ix < inbndry) && ((inner_boundary_flags & INVERT_SET) != 0) - && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && ((outer_boundary_flags & INVERT_SET) != 0) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary rfft(x0[ix], localmesh->LocalNz, std::begin(k1d)); } else { @@ -259,14 +256,13 @@ FieldPerp LaplacePCR_THOMAS::solve(const FieldPerp& rhs, const FieldPerp& x0) { // Get elements of the tridiagonal matrix // including boundary conditions - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int kz = 0; kz < nmode; kz++) { const BoutReal kwave = kz * 2.0 * PI / zlength; // wave number is 1/[rad] tridagMatrix(&a(kz, 0), &b(kz, 0), &c(kz, 0), &bcmplx(kz, 0), jy, kz, // True for the component constant (DC) in Z kwave, // Z wave number - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false); // Don't include guard cells in arrays } } @@ -275,15 +271,15 @@ FieldPerp LaplacePCR_THOMAS::solve(const FieldPerp& rhs, const FieldPerp& x0) { pcr_thomas_solver(a, b, c, bcmplx, xcmplx); // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array((localmesh->LocalNz) / 2 + 1); // ZFFT routine expects input of this length - const bool zero_DC = (global_flags & INVERT_ZERO_DC) != 0; + const bool zero_DC = isGlobalFlagSet(INVERT_ZERO_DC); - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ix = xs; ix <= xe; ix++) { if (zero_DC) { k1d[0] = 0.; @@ -323,13 +319,13 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { // If the flags to assign that only one guard cell should be used is set int inbndry = localmesh->xstart; int outbndry = localmesh->xstart; - if (((global_flags & INVERT_BOTH_BNDRY_ONE) != 0) || (localmesh->xstart < 2)) { + if (isGlobalFlagSet(INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { inbndry = outbndry = 1; } - if ((inner_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isInnerBoundaryFlagSet(INVERT_BNDRY_ONE)) { inbndry = 1; } - if ((outer_boundary_flags & INVERT_BNDRY_ONE) != 0) { + if (isOuterBoundaryFlagSet(INVERT_BNDRY_ONE)) { outbndry = 1; } @@ -367,7 +363,7 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { if (dst) { const BoutReal zlength = getUniform(coords->dz) * (localmesh->LocalNz - 3); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array( @@ -375,7 +371,7 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { // Loop over X and Y indices, including boundaries but not guard cells. // (unless periodic in x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ind = 0; ind < nxny; ++ind) { // ind = (ix - xs)*(ye - ys + 1) + (iy - ys) int ix = xs + ind / ny; @@ -383,10 +379,9 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { // Take DST in Z direction and put result in k1d - if (((ix < inbndry) && ((inner_boundary_flags & INVERT_SET) != 0) - && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && ((outer_boundary_flags & INVERT_SET) != 0) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary DST(x0(ix, iy) + 1, localmesh->LocalNz - 2, std::begin(k1d)); } else { @@ -401,7 +396,7 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { // Get elements of the tridiagonal matrix // including boundary conditions - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nsys; ind++) { // ind = (iy - ys) * nmode + kz int iy = ys + ind / nmode; @@ -413,8 +408,7 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { tridagMatrix(&a3D(ind, 0), &b3D(ind, 0), &c3D(ind, 0), &bcmplx3D(ind, 0), iy, kz, // wave number index kwave, // kwave (inverse wave length) - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false); // Don't include guard cells in arrays } } @@ -423,13 +417,13 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { pcr_thomas_solver(a3D, b3D, c3D, bcmplx3D, xcmplx3D); // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array( localmesh->LocalNz); // ZFFT routine expects input of this length - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nxny; ++ind) { // Loop over X and Y // ind = (ix - xs)*(ye - ys + 1) + (iy - ys) int ix = xs + ind / ny; @@ -451,7 +445,7 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { } } else { const BoutReal zlength = getUniform(coords->zlength()); - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array(localmesh->LocalNz / 2 @@ -460,7 +454,7 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { // Loop over X and Y indices, including boundaries but not guard cells // (unless periodic in x) - BOUT_OMP(for) + BOUT_OMP_PERF(for) for (int ind = 0; ind < nxny; ++ind) { // ind = (ix - xs)*(ye - ys + 1) + (iy - ys) int ix = xs + ind / ny; @@ -468,10 +462,9 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { // Take FFT in Z direction, apply shift, and put result in k1d - if (((ix < inbndry) && ((inner_boundary_flags & INVERT_SET) != 0) - && localmesh->firstX()) + if (((ix < inbndry) && isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) || ((localmesh->LocalNx - ix - 1 < outbndry) - && ((outer_boundary_flags & INVERT_SET) != 0) && localmesh->lastX())) { + && isOuterBoundaryFlagSetOnLastX(INVERT_SET))) { // Use the values in x0 in the boundary rfft(x0(ix, iy), localmesh->LocalNz, std::begin(k1d)); } else { @@ -486,7 +479,7 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { // Get elements of the tridiagonal matrix // including boundary conditions - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nsys; ind++) { // ind = (iy - ys) * nmode + kz int iy = ys + ind / nmode; @@ -497,8 +490,7 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { tridagMatrix(&a3D(ind, 0), &b3D(ind, 0), &c3D(ind, 0), &bcmplx3D(ind, 0), iy, kz, // True for the component constant (DC) in Z kwave, // Z wave number - global_flags, inner_boundary_flags, outer_boundary_flags, &Acoef, - &C1coef, &C2coef, &Dcoef, + &Acoef, &C1coef, &C2coef, &Dcoef, false); // Don't include guard cells in arrays } } @@ -507,15 +499,15 @@ Field3D LaplacePCR_THOMAS::solve(const Field3D& rhs, const Field3D& x0) { pcr_thomas_solver(a3D, b3D, c3D, bcmplx3D, xcmplx3D); // FFT back to real space - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { /// Create a local thread-scope working array auto k1d = Array((localmesh->LocalNz) / 2 + 1); // ZFFT routine expects input of this length - const bool zero_DC = (global_flags & INVERT_ZERO_DC) != 0; + const bool zero_DC = isGlobalFlagSet(INVERT_ZERO_DC); - BOUT_OMP(for nowait) + BOUT_OMP_PERF(for nowait) for (int ind = 0; ind < nxny; ++ind) { // Loop over X and Y int ix = xs + ind / ny; int iy = ys + ind % ny; diff --git a/src/invert/laplace/impls/pcr_thomas/pcr_thomas.hxx b/src/invert/laplace/impls/pcr_thomas/pcr_thomas.hxx index 009a1def2b..e12a647789 100644 --- a/src/invert/laplace/impls/pcr_thomas/pcr_thomas.hxx +++ b/src/invert/laplace/impls/pcr_thomas/pcr_thomas.hxx @@ -175,14 +175,6 @@ private: /// First and last interior points xstart, xend int xs, xe; - bool isGlobalFlagSet(int flag) const { return (global_flags & flag) != 0; } - bool isInnerBoundaryFlagSet(int flag) const { - return (inner_boundary_flags & flag) != 0; - } - bool isOuterBoundaryFlagSet(int flag) const { - return (outer_boundary_flags & flag) != 0; - } - bool dst{false}; }; diff --git a/src/invert/laplace/impls/petsc/makefile b/src/invert/laplace/impls/petsc/makefile deleted file mode 100644 index e60d45292c..0000000000 --- a/src/invert/laplace/impls/petsc/makefile +++ /dev/null @@ -1,10 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = petsc_laplace.cxx -SOURCEH = petsc_laplace.hxx -TARGET = lib - -CXXFLAGS +=-g - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/petsc/petsc_laplace.cxx b/src/invert/laplace/impls/petsc/petsc_laplace.cxx index d125b90694..f06f4c7de6 100644 --- a/src/invert/laplace/impls/petsc/petsc_laplace.cxx +++ b/src/invert/laplace/impls/petsc/petsc_laplace.cxx @@ -23,7 +23,8 @@ * along with BOUT++. If not, see . * **************************************************************************/ -#include "bout/build_config.hxx" + +#include "bout/build_defines.hxx" #if BOUT_HAS_PETSC @@ -32,6 +33,8 @@ #include #include #include +#include +#include #include #include @@ -49,14 +52,13 @@ #define KSP_PREONLY "preonly" static PetscErrorCode laplacePCapply(PC pc, Vec x, Vec y) { - int ierr; + PetscFunctionBegin; // NOLINT - // Get the context - LaplacePetsc* s; - ierr = PCShellGetContext(pc, reinterpret_cast(&s)); + LaplacePetsc* laplace = nullptr; + const int ierr = PCShellGetContext(pc, reinterpret_cast(&laplace)); // NOLINT CHKERRQ(ierr); - PetscFunctionReturn(s->precon(x, y)); + PetscFunctionReturn(laplace->precon(x, y)); // NOLINT } LaplacePetsc::LaplacePetsc(Options* opt, const CELL_LOC loc, Mesh* mesh_in, @@ -79,28 +81,9 @@ LaplacePetsc::LaplacePetsc(Options* opt, const CELL_LOC loc, Mesh* mesh_in, } #if CHECK > 0 - // These are the implemented flags - implemented_flags = INVERT_START_NEW; - implemented_boundary_flags = INVERT_AC_GRAD + INVERT_SET + INVERT_RHS; // Checking flags are set to something which is not implemented - // This is done binary (which is possible as each flag is a power of 2) - if (global_flags & ~implemented_flags) { - if (global_flags & INVERT_4TH_ORDER) { - output << "For PETSc based Laplacian inverter, use 'fourth_order=true' instead of " - "setting INVERT_4TH_ORDER flag" - << endl; - } - throw BoutException("Attempted to set Laplacian inversion flag that is not " - "implemented in petsc_laplace.cxx"); - } - if (inner_boundary_flags & ~implemented_boundary_flags) { - throw BoutException("Attempted to set Laplacian inversion boundary flag that is not " - "implemented in petsc_laplace.cxx"); - } - if (outer_boundary_flags & ~implemented_boundary_flags) { - throw BoutException("Attempted to set Laplacian inversion boundary flag that is not " - "implemented in petsc_laplace.cxx"); - } + checkFlags(); + if (localmesh->periodicX) { throw BoutException("LaplacePetsc does not work with periodicity in the x direction " "(localmesh->PeriodicX == true). Change boundary conditions or " @@ -360,25 +343,7 @@ FieldPerp LaplacePetsc::solve(const FieldPerp& b, const FieldPerp& x0) { ASSERT1(x0.getLocation() == location); #if CHECK > 0 - // Checking flags are set to something which is not implemented (see - // constructor for details) - if (global_flags & !implemented_flags) { - if (global_flags & INVERT_4TH_ORDER) { - output << "For PETSc based Laplacian inverter, use 'fourth_order=true' instead of " - "setting INVERT_4TH_ORDER flag" - << endl; - } - throw BoutException("Attempted to set Laplacian inversion flag that is not " - "implemented in petsc_laplace.cxx"); - } - if (inner_boundary_flags & ~implemented_boundary_flags) { - throw BoutException("Attempted to set Laplacian inversion boundary flag that is not " - "implemented in petsc_laplace.cxx"); - } - if (outer_boundary_flags & ~implemented_boundary_flags) { - throw BoutException("Attempted to set Laplacian inversion boundary flag that is not " - "implemented in petsc_laplace.cxx"); - } + checkFlags(); #endif int y = b.getIndex(); // Get the Y index @@ -415,7 +380,7 @@ FieldPerp LaplacePetsc::solve(const FieldPerp& b, const FieldPerp& x0) { for (int z = 0; z < localmesh->LocalNz; z++) { PetscScalar val; // Value of element to be set in the matrix // If Neumann Boundary Conditions are set. - if (inner_boundary_flags & INVERT_AC_GRAD) { + if (isInnerBoundaryFlagSet(INVERT_AC_GRAD)) { // Set values corresponding to nodes adjacent in x if (fourth_order) { // Fourth Order Accuracy on Boundary @@ -472,9 +437,9 @@ FieldPerp LaplacePetsc::solve(const FieldPerp& b, const FieldPerp& x0) { // Set Components of RHS // If the inner boundary value should be set by b or x0 - if (inner_boundary_flags & INVERT_RHS) { + if (isInnerBoundaryFlagSet(INVERT_RHS)) { val = b[x][z]; - } else if (inner_boundary_flags & INVERT_SET) { + } else if (isInnerBoundaryFlagSet(INVERT_SET)) { val = x0[x][z]; } @@ -680,7 +645,7 @@ FieldPerp LaplacePetsc::solve(const FieldPerp& b, const FieldPerp& x0) { Element(i, x, z, 0, 0, val, MatA); // If Neumann Boundary Conditions are set. - if (outer_boundary_flags & INVERT_AC_GRAD) { + if (isOuterBoundaryFlagSet(INVERT_AC_GRAD)) { // Set values corresponding to nodes adjacent in x if (fourth_order) { // Fourth Order Accuracy on Boundary @@ -733,9 +698,9 @@ FieldPerp LaplacePetsc::solve(const FieldPerp& b, const FieldPerp& x0) { // Set Components of RHS // If the inner boundary value should be set by b or x0 val = 0; - if (outer_boundary_flags & INVERT_RHS) { + if (isOuterBoundaryFlagSet(INVERT_RHS)) { val = b[x][z]; - } else if (outer_boundary_flags & INVERT_SET) { + } else if (isOuterBoundaryFlagSet(INVERT_SET)) { val = x0[x][z]; } @@ -812,7 +777,7 @@ FieldPerp LaplacePetsc::solve(const FieldPerp& b, const FieldPerp& x0) { KSPSetTolerances(ksp, rtol, atol, dtol, maxits); // If the initial guess is not set to zero - if (!(global_flags & INVERT_START_NEW)) { + if (!isGlobalFlagSet(INVERT_START_NEW)) { KSPSetInitialGuessNonzero(ksp, static_cast(true)); } @@ -1194,4 +1159,24 @@ int LaplacePetsc::precon(Vec x, Vec y) { return 0; } +void LaplacePetsc::checkFlags() { + if (isGlobalFlagSet(~implemented_flags)) { + if (isGlobalFlagSet(INVERT_4TH_ORDER)) { + output_error.write( + "For PETSc based Laplacian inverter, use 'fourth_order=true' instead of " + "setting INVERT_4TH_ORDER flag\n"); + } + throw BoutException("Attempted to set Laplacian inversion flag that is not " + "implemented in petsc_laplace.cxx"); + } + if (isInnerBoundaryFlagSet(~implemented_boundary_flags)) { + throw BoutException("Attempted to set Laplacian inversion boundary flag that is not " + "implemented in petsc_laplace.cxx"); + } + if (isOuterBoundaryFlagSet(~implemented_boundary_flags)) { + throw BoutException("Attempted to set Laplacian inversion boundary flag that is not " + "implemented in petsc_laplace.cxx"); + } +} + #endif // BOUT_HAS_PETSC_3_3 diff --git a/src/invert/laplace/impls/petsc/petsc_laplace.hxx b/src/invert/laplace/impls/petsc/petsc_laplace.hxx index 3b1d3bcb49..55482644be 100644 --- a/src/invert/laplace/impls/petsc/petsc_laplace.hxx +++ b/src/invert/laplace/impls/petsc/petsc_laplace.hxx @@ -26,8 +26,8 @@ * **************************************************************************/ -#ifndef __PETSC_LAPLACE_H__ -#define __PETSC_LAPLACE_H__ +#ifndef BOUT_PETSC_LAPLACE_H +#define BOUT_PETSC_LAPLACE_H #include "bout/build_config.hxx" #include "bout/invert_laplace.hxx" @@ -254,12 +254,13 @@ private: void vecToField(Vec x, FieldPerp& f); // Copy a vector into a fieldperp void fieldToVec(const FieldPerp& f, Vec x); // Copy a fieldperp into a vector -#if CHECK > 0 - int implemented_flags; - int implemented_boundary_flags; -#endif + static constexpr int implemented_flags = INVERT_START_NEW; + static constexpr int implemented_boundary_flags = + INVERT_AC_GRAD | INVERT_SET | INVERT_RHS; + + void checkFlags(); }; #endif //BOUT_HAS_PETSC -#endif //__PETSC_LAPLACE_H__ +#endif //BOUT_PETSC_LAPLACE_H diff --git a/src/invert/laplace/impls/petsc3damg/makefile b/src/invert/laplace/impls/petsc3damg/makefile deleted file mode 100644 index 124b2cc607..0000000000 --- a/src/invert/laplace/impls/petsc3damg/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = petsc3damg.cxx -SOURCEH = petsc3damg.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/petsc3damg/petsc3damg.cxx b/src/invert/laplace/impls/petsc3damg/petsc3damg.cxx index 633e938ccc..a7bfd209ee 100644 --- a/src/invert/laplace/impls/petsc3damg/petsc3damg.cxx +++ b/src/invert/laplace/impls/petsc3damg/petsc3damg.cxx @@ -24,6 +24,7 @@ * along with BOUT++. If not, see . * **************************************************************************/ +#include "bout/bout_types.hxx" #include "bout/build_config.hxx" #if BOUT_HAS_PETSC @@ -39,14 +40,37 @@ #include #include +using bout::utils::flagSet; + +#ifdef PETSC_HAVE_HYPRE +static constexpr auto DEFAULT_PC_TYPE = PCHYPRE; +#else +static constexpr auto DEFAULT_PC_TYPE = PCGAMG; +#endif // PETSC_HAVE_HYPRE + LaplacePetsc3dAmg::LaplacePetsc3dAmg(Options* opt, const CELL_LOC loc, Mesh* mesh_in, Solver* UNUSED(solver)) : Laplacian(opt, loc, mesh_in), A(0.0), C1(1.0), C2(1.0), D(1.0), Ex(0.0), Ez(0.0), + opts(opt == nullptr ? &(Options::root()["laplace"]) : opt), + lower_boundary_flags((*opts)["lower_boundary_flags"].withDefault(0)), + upper_boundary_flags((*opts)["upper_boundary_flags"].withDefault(0)), + ksptype((*opts)["ksptype"].doc("KSP solver type").withDefault(KSPGMRES)), + pctype((*opts)["pctype"].doc("PC type").withDefault(DEFAULT_PC_TYPE)), + richardson_damping_factor((*opts)["richardson_damping_factor"].withDefault(1.0)), + chebyshev_max((*opts)["chebyshev_max"].withDefault(100.0)), + chebyshev_min((*opts)["chebyshev_min"].withDefault(0.01)), + gmres_max_steps((*opts)["gmres_max_steps"].withDefault(30)), + rtol((*opts)["rtol"].doc("Relative tolerance for KSP solver").withDefault(1e-5)), + atol((*opts)["atol"].doc("Absolute tolerance for KSP solver").withDefault(1e-5)), + dtol((*opts)["dtol"].doc("Divergence tolerance for KSP solver").withDefault(1e6)), + maxits( + (*opts)["maxits"].doc("Maximum number of KSP iterations").withDefault(100000)), + direct((*opts)["direct"].doc("Use direct (LU) solver?").withDefault(false)), lowerY(localmesh->iterateBndryLowerY()), upperY(localmesh->iterateBndryUpperY()), indexer(std::make_shared>( localmesh, getStencil(localmesh, lowerY, upperY))), - operator3D(indexer), kspInitialised(false), - lib(opt == nullptr ? &(Options::root()["laplace"]) : opt) { + operator3D(indexer), lib(opts) { + // Provide basic initialisation of field coefficients, etc. // Get relevent options from user input // Initialise PETSc objects @@ -57,45 +81,32 @@ LaplacePetsc3dAmg::LaplacePetsc3dAmg(Options* opt, const CELL_LOC loc, Mesh* mes Ex.setLocation(location); Ez.setLocation(location); - // Get Options in Laplace Section - if (!opt) { - opts = Options::getRoot()->getSection("laplace"); - } else { - opts = opt; - } - - // Get y boundary flags - lower_boundary_flags = (*opts)["lower_boundary_flags"].withDefault(0); - upper_boundary_flags = (*opts)["upper_boundary_flags"].withDefault(0); - #if CHECK > 0 // Checking flags are set to something which is not implemented // This is done binary (which is possible as each flag is a power of 2) - if ((global_flags & ~implemented_flags) != 0) { - if ((global_flags & INVERT_4TH_ORDER) != 0) { - output << "For PETSc based Laplacian inverter, use 'fourth_order=true' instead of " - "setting INVERT_4TH_ORDER flag" - << "\n"; - } - throw BoutException("Attempted to set Laplacian inversion flag that is not " - "implemented in petsc_laplace.cxx"); - } - if ((inner_boundary_flags & ~implemented_boundary_flags) != 0) { - throw BoutException("Attempted to set Laplacian inversion boundary flag that is not " - "implemented in petsc_laplace.cxx"); - } - if ((outer_boundary_flags & ~implemented_boundary_flags) != 0) { - throw BoutException("Attempted to set Laplacian inversion boundary flag that is not " - "implemented in petsc_laplace.cxx"); - } - if ((lower_boundary_flags & ~implemented_boundary_flags) != 0) { - throw BoutException("Attempted to set Laplacian inversion boundary flag that is not " - "implemented in petsc_laplace.cxx"); + if (isGlobalFlagSet(INVERT_4TH_ORDER)) { + output.write("For PETSc based Laplacian inverter, use 'fourth_order=true' instead of " + "setting INVERT_4TH_ORDER flag\n"); } - if ((upper_boundary_flags & ~implemented_boundary_flags) != 0) { - throw BoutException("Attempted to set Laplacian inversion boundary flag that is not " + + if (isGlobalFlagSet(~implemented_flags)) { + throw BoutException("Attempted to set global Laplacian inversion flag that is not " "implemented in petsc_laplace.cxx"); } + + auto unimplementedBoundaryFlag = [](int boundary_flag, + const std::string& name) -> void { + if (flagSet(boundary_flag, ~implemented_boundary_flags)) { + throw BoutException("Attempted to set Laplacian inversion {} boundary flag " + "that is not implemented in petsc3damg.cxx", + name); + } + }; + unimplementedBoundaryFlag(getInnerBoundaryFlags(), "inner"); + unimplementedBoundaryFlag(getOuterBoundaryFlags(), "outer"); + unimplementedBoundaryFlag(lower_boundary_flags, "lower"); + unimplementedBoundaryFlag(upper_boundary_flags, "upper"); + if (localmesh->periodicX) { throw BoutException("LaplacePetsc3dAmg does not work with periodicity in the x " "direction (localmesh->PeriodicX == true). Change boundary " @@ -103,85 +114,45 @@ LaplacePetsc3dAmg::LaplacePetsc3dAmg(Options* opt, const CELL_LOC loc, Mesh* mes } #endif - // Get Tolerances for KSP solver - rtol = (*opts)["rtol"].doc("Relative tolerance for KSP solver").withDefault(1e-5); - atol = (*opts)["atol"].doc("Absolute tolerance for KSP solver").withDefault(1e-5); - dtol = (*opts)["dtol"].doc("Divergence tolerance for KSP solver").withDefault(1e6); - maxits = (*opts)["maxits"].doc("Maximum number of KSP iterations").withDefault(100000); - - richardson_damping_factor = (*opts)["richardson_damping_factor"].withDefault(1.0); - chebyshev_max = (*opts)["chebyshev_max"].withDefault(100.0); - chebyshev_min = (*opts)["chebyshev_min"].withDefault(0.01); - gmres_max_steps = (*opts)["gmres_max_steps"].withDefault(30); - - // Get KSP Solver Type (Generalizes Minimal RESidual is the default) - ksptype = (*opts)["ksptype"].doc("KSP solver type").withDefault(KSPGMRES); - - // Get preconditioner type -#ifdef PETSC_HAVE_HYPRE - // PETSc was compiled with Hypre - pctype = (*opts)["pctype"].doc("PC type").withDefault(PCHYPRE); -#else - // Hypre not available - pctype = (*opts)["pctype"].doc("PC type").withDefault(PCGAMG); -#endif // PETSC_HAVE_HYPRE - - // Get direct solver switch - direct = (*opts)["direct"].doc("Use direct (LU) solver?").withDefault(false); if (direct) { - output << "\n" - << "Using LU decompostion for direct solution of system" - << "\n" - << "\n"; + output.write("\nUsing LU decompostion for direct solution of system\n\n"); } // Set up boundary conditions in operator + const bool inner_X_neumann = isInnerBoundaryFlagSet(INVERT_AC_GRAD); + const auto inner_X_BC = inner_X_neumann ? -1. / coords->dx / sqrt(coords->g_11) : 0.5; + const auto inner_X_BC_plus = inner_X_neumann ? -inner_X_BC : 0.5; + BOUT_FOR_SERIAL(i, indexer->getRegionInnerX()) { - if ((inner_boundary_flags & INVERT_AC_GRAD) != 0) { - // Neumann on inner X boundary - operator3D(i, i) = -1. / coords->dx[i] / sqrt(coords->g_11[i]); - operator3D(i, i.xp()) = 1. / coords->dx[i] / sqrt(coords->g_11[i]); - } else { - // Dirichlet on inner X boundary - operator3D(i, i) = 0.5; - operator3D(i, i.xp()) = 0.5; - } + operator3D(i, i) = inner_X_BC[i]; + operator3D(i, i.xp()) = inner_X_BC_plus[i]; } + const bool outer_X_neumann = isOuterBoundaryFlagSet(INVERT_AC_GRAD); + const auto outer_X_BC = outer_X_neumann ? 1. / coords->dx / sqrt(coords->g_11) : 0.5; + const auto outer_X_BC_minus = outer_X_neumann ? -outer_X_BC : 0.5; + BOUT_FOR_SERIAL(i, indexer->getRegionOuterX()) { - if ((outer_boundary_flags & INVERT_AC_GRAD) != 0) { - // Neumann on outer X boundary - operator3D(i, i) = 1. / coords->dx[i] / sqrt(coords->g_11[i]); - operator3D(i, i.xm()) = -1. / coords->dx[i] / sqrt(coords->g_11[i]); - } else { - // Dirichlet on outer X boundary - operator3D(i, i) = 0.5; - operator3D(i, i.xm()) = 0.5; - } + operator3D(i, i) = outer_X_BC[i]; + operator3D(i, i.xm()) = outer_X_BC_minus[i]; } + const bool lower_Y_neumann = flagSet(lower_boundary_flags, INVERT_AC_GRAD); + const auto lower_Y_BC = lower_Y_neumann ? -1. / coords->dy / sqrt(coords->g_22) : 0.5; + const auto lower_Y_BC_plus = lower_Y_neumann ? -lower_Y_BC : 0.5; + BOUT_FOR_SERIAL(i, indexer->getRegionLowerY()) { - if ((lower_boundary_flags & INVERT_AC_GRAD) != 0) { - // Neumann on lower Y boundary - operator3D(i, i) = -1. / coords->dy[i] / sqrt(coords->g_22[i]); - operator3D(i, i.yp()) = 1. / coords->dy[i] / sqrt(coords->g_22[i]); - } else { - // Dirichlet on lower Y boundary - operator3D(i, i) = 0.5; - operator3D(i, i.yp()) = 0.5; - } + operator3D(i, i) = lower_Y_BC[i]; + operator3D(i, i.yp()) = lower_Y_BC_plus[i]; } + const bool upper_Y_neumann = flagSet(upper_boundary_flags, INVERT_AC_GRAD); + const auto upper_Y_BC = upper_Y_neumann ? 1. / coords->dy / sqrt(coords->g_22) : 0.5; + const auto upper_Y_BC_minus = upper_Y_neumann ? -upper_Y_BC : 0.5; + BOUT_FOR_SERIAL(i, indexer->getRegionUpperY()) { - if ((upper_boundary_flags & INVERT_AC_GRAD) != 0) { - // Neumann on upper Y boundary - operator3D(i, i) = 1. / coords->dy[i] / sqrt(coords->g_22[i]); - operator3D(i, i.ym()) = -1. / coords->dy[i] / sqrt(coords->g_22[i]); - } else { - // Dirichlet on upper Y boundary - operator3D(i, i) = 0.5; - operator3D(i, i.ym()) = 0.5; - } + operator3D(i, i) = upper_Y_BC[i]; + operator3D(i, i.ym()) = upper_Y_BC_minus[i]; } } @@ -191,69 +162,46 @@ LaplacePetsc3dAmg::~LaplacePetsc3dAmg() { } } +void setBC(PetscVector& rhs, const Field3D& b_in, + const Region& region, int boundary_flags, + const Field3D& x0) { + if (flagSet(boundary_flags, INVERT_RHS)) { + BOUT_FOR(index, region) { ASSERT1(std::isfinite(b_in[index])); } + } else { + const auto& outer_X_BC = (flagSet(boundary_flags, INVERT_SET)) ? x0 : 0.0; + BOUT_FOR_SERIAL(index, region) { rhs(index) = outer_X_BC[index]; } + } +} + Field3D LaplacePetsc3dAmg::solve(const Field3D& b_in, const Field3D& x0) { AUTO_TRACE(); // Timing reported in the log files. Includes any matrix construction. // The timing for just the solve phase can be retrieved from the "petscsolve" // timer if desired. - Timer timer("invert"); + const Timer timer("invert"); // If necessary, update the values in the matrix operator and initialise // the Krylov solver if (updateRequired) { updateMatrix3D(); } - PetscVector rhs(b_in, indexer), guess(x0, indexer); + PetscVector rhs(b_in, indexer); + PetscVector guess(x0, indexer); // Adjust vectors to represent boundary conditions and check that // boundary cells are finite - BOUT_FOR_SERIAL(i, indexer->getRegionInnerX()) { - const BoutReal val = (inner_boundary_flags & INVERT_SET) ? x0[i] : 0.; - ASSERT1(std::isfinite(x0[i])); - if (!(inner_boundary_flags & INVERT_RHS)) { - rhs(i) = val; - } else { - ASSERT1(std::isfinite(b_in[i])); - } - } - - BOUT_FOR_SERIAL(i, indexer->getRegionOuterX()) { - const BoutReal val = (outer_boundary_flags & INVERT_SET) ? x0[i] : 0.; - ASSERT1(std::isfinite(x0[i])); - if (!(outer_boundary_flags & INVERT_RHS)) { - rhs(i) = val; - } else { - ASSERT1(std::isfinite(b_in[i])); - } - } - - BOUT_FOR_SERIAL(i, indexer->getRegionLowerY()) { - const BoutReal val = (lower_boundary_flags & INVERT_SET) ? x0[i] : 0.; - ASSERT1(std::isfinite(x0[i])); - if (!(lower_boundary_flags & INVERT_RHS)) { - rhs(i) = val; - } else { - ASSERT1(std::isfinite(b_in[i])); - } - } - - BOUT_FOR_SERIAL(i, indexer->getRegionUpperY()) { - const BoutReal val = (upper_boundary_flags & INVERT_SET) ? x0[i] : 0.; - ASSERT1(std::isfinite(x0[i])); - if (!(upper_boundary_flags & INVERT_RHS)) { - rhs(i) = val; - } else { - ASSERT1(std::isfinite(b_in[i])); - } - } + setBC(rhs, b_in, indexer->getRegionInnerX(), getInnerBoundaryFlags(), x0); + setBC(rhs, b_in, indexer->getRegionOuterX(), getOuterBoundaryFlags(), x0); + setBC(rhs, b_in, indexer->getRegionLowerY(), lower_boundary_flags, x0); + setBC(rhs, b_in, indexer->getRegionUpperY(), upper_boundary_flags, x0); rhs.assemble(); guess.assemble(); // Invoke solver { - Timer timer("petscsolve"); + const Timer timer("petscsolve"); KSPSolve(ksp, *rhs.get(), *guess.get()); } @@ -276,11 +224,13 @@ Field3D LaplacePetsc3dAmg::solve(const Field3D& b_in, const Field3D& x0) { if (solution.hasParallelSlices()) { BOUT_FOR(i, indexer->getRegionLowerY()) { solution.ydown()[i] = solution[i]; } BOUT_FOR(i, indexer->getRegionUpperY()) { solution.yup()[i] = solution[i]; } - for (int b = 1; b < localmesh->ystart; b++) { + for (int boundary = 1; boundary < localmesh->ystart; boundary++) { BOUT_FOR(i, indexer->getRegionLowerY()) { - solution.ydown(b)[i.ym(b)] = solution[i]; + solution.ydown(boundary)[i.ym(boundary)] = solution[i]; + } + BOUT_FOR(i, indexer->getRegionUpperY()) { + solution.yup(boundary)[i.yp(boundary)] = solution[i]; } - BOUT_FOR(i, indexer->getRegionUpperY()) { solution.yup(b)[i.yp(b)] = solution[i]; } } } @@ -289,9 +239,10 @@ Field3D LaplacePetsc3dAmg::solve(const Field3D& b_in, const Field3D& x0) { // Note: RegionInnerX is the set of points just outside the domain // (in the first boundary cell) so one boundary cell is already set BOUT_FOR(i, indexer->getRegionInnerX()) { - for (int b = 1; b < localmesh->xstart; b++) { - solution[i.xm(b)] = - 3. * solution[i.xm(b - 1)] - 3. * solution[i.xm(b - 2)] + solution[i.xm(b - 3)]; + for (int boundary = 1; boundary < localmesh->xstart; boundary++) { + solution[i.xm(boundary)] = 3. * solution[i.xm(boundary - 1)] + - 3. * solution[i.xm(boundary - 2)] + + solution[i.xm(boundary - 3)]; } } @@ -299,9 +250,10 @@ Field3D LaplacePetsc3dAmg::solve(const Field3D& b_in, const Field3D& x0) { // Note: RegionOuterX is the set of points just outside the domain // (in the first boundary cell) so one boundary cell is already set BOUT_FOR(i, indexer->getRegionOuterX()) { - for (int b = 1; b < localmesh->xstart; b++) { - solution[i.xp(b)] = - 3. * solution[i.xp(b - 1)] - 3. * solution[i.xp(b - 2)] + solution[i.xp(b - 3)]; + for (int boundary = 1; boundary < localmesh->xstart; boundary++) { + solution[i.xp(boundary)] = 3. * solution[i.xp(boundary - 1)] + - 3. * solution[i.xp(boundary - 2)] + + solution[i.xp(boundary - 3)]; } } @@ -332,7 +284,8 @@ void LaplacePetsc3dAmg::updateMatrix3D() { // avoid confusing it with the x-index. // Calculate coefficients for the terms in the differential operator - BoutReal C_df_dx = coords->G1[l], C_df_dz = coords->G3[l]; + BoutReal C_df_dx = coords->G1[l]; + BoutReal C_df_dz = coords->G3[l]; if (issetD) { C_df_dx *= D[l]; C_df_dz *= D[l]; @@ -350,9 +303,9 @@ void LaplacePetsc3dAmg::updateMatrix3D() { C_df_dz += Ez[l]; } - BoutReal C_d2f_dx2 = coords->g11[l], - C_d2f_dy2 = (coords->g22[l] - 1.0 / coords->g_22[l]), - C_d2f_dz2 = coords->g33[l]; + BoutReal C_d2f_dx2 = coords->g11[l]; + BoutReal C_d2f_dy2 = (coords->g22[l] - 1.0 / coords->g_22[l]); + BoutReal C_d2f_dz2 = coords->g33[l]; if (issetD) { C_d2f_dx2 *= D[l]; C_d2f_dy2 *= D[l]; @@ -389,8 +342,8 @@ void LaplacePetsc3dAmg::updateMatrix3D() { // The values stored in the y-boundary are already interpolated // up/down, so we don't want the matrix to do any such // interpolation there. - const int yup = (l.y() == localmesh->yend && upperY.intersects(l.x())) ? -1 : 0, - ydown = (l.y() == localmesh->ystart && lowerY.intersects(l.x())) ? -1 : 0; + const int yup = (l.y() == localmesh->yend && upperY.intersects(l.x())) ? -1 : 0; + const int ydown = (l.y() == localmesh->ystart && lowerY.intersects(l.x())) ? -1 : 0; operator3D.yup(yup)(l, l.yp()) = 0.0; operator3D.ydown(ydown)(l, l.ym()) = 0.0; operator3D.yup(yup)(l, l.xp().yp()) = 0.0; @@ -423,7 +376,8 @@ void LaplacePetsc3dAmg::updateMatrix3D() { C_d2f_dy2 *= D[l]; } - BoutReal C_d2f_dxdy = 2 * coords->g12[l], C_d2f_dydz = 2 * coords->g23[l]; + BoutReal C_d2f_dxdy = 2 * coords->g12[l]; + BoutReal C_d2f_dydz = 2 * coords->g23[l]; if (issetD) { C_d2f_dxdy *= D[l]; C_d2f_dydz *= D[l]; @@ -444,8 +398,8 @@ void LaplacePetsc3dAmg::updateMatrix3D() { // The values stored in the y-boundary are already interpolated // up/down, so we don't want the matrix to do any such // interpolation there. - const int yup = (l.y() == localmesh->yend && upperY.intersects(l.x())) ? -1 : 0, - ydown = (l.y() == localmesh->ystart && lowerY.intersects(l.x())) ? -1 : 0; + const int yup = (l.y() == localmesh->yend && upperY.intersects(l.x())) ? -1 : 0; + const int ydown = (l.y() == localmesh->ystart && lowerY.intersects(l.x())) ? -1 : 0; operator3D.yup(yup)(l, l.yp()) += C_df_dy + C_d2f_dy2; operator3D.ydown(ydown)(l, l.ym()) += -C_df_dy + C_d2f_dy2; @@ -473,7 +427,7 @@ void LaplacePetsc3dAmg::updateMatrix3D() { KSPSetOperators(ksp, *operator3D.get(), *operator3D.get(), DIFFERENT_NONZERO_PATTERN); #endif - PC pc; + PC pc = nullptr; KSPGetPC(ksp, &pc); if (direct) { @@ -506,7 +460,7 @@ void LaplacePetsc3dAmg::updateMatrix3D() { KSPSetTolerances(ksp, rtol, atol, dtol, maxits); // If the initial guess is not set to zero - if ((global_flags & INVERT_START_NEW) == 0) { + if (!isGlobalFlagSet(INVERT_START_NEW)) { KSPSetInitialGuessNonzero(ksp, (PetscBool) true); } @@ -528,33 +482,32 @@ OperatorStencil LaplacePetsc3dAmg::getStencil(Mesh* localmesh, // Get the pattern used for interpolation. This is assumed to be the // same across the whole grid. - const auto pw = + const auto positions_weights = localmesh->getCoordinates()->getParallelTransform().getWeightsForYDownApproximation( localmesh->xstart, localmesh->ystart + 1, localmesh->zstart); std::vector interpPattern; - std::transform(pw.begin(), pw.end(), std::back_inserter(interpPattern), - [localmesh](ParallelTransform::PositionsAndWeights p) -> OffsetInd3D { - return {localmesh->xstart - p.i, localmesh->ystart - p.j, - localmesh->LocalNz - p.k < p.k ? p.k - localmesh->LocalNz - : p.k}; - }); - - OffsetInd3D zero; + std::transform( + positions_weights.begin(), positions_weights.end(), + std::back_inserter(interpPattern), + [localmesh](ParallelTransform::PositionsAndWeights position) -> OffsetInd3D { + return {localmesh->xstart - position.i, localmesh->ystart - position.j, + ((localmesh->LocalNz - position.k) < position.k) + ? position.k - localmesh->LocalNz + : position.k}; + }); + + const OffsetInd3D zero; // Add interior cells - const std::vector interpolatedUpElements = {zero.yp(), zero.xp().yp(), - zero.xm().yp(), zero.yp().zp(), - zero.yp().zm()}, - interpolatedDownElements = { - zero.ym(), zero.xp().ym(), zero.xm().ym(), - zero.ym().zp(), zero.ym().zm()}; - std::set interiorStencil = {zero, zero.xp(), - zero.xm(), zero.zp(), - zero.zm(), zero.xp().zp(), - zero.xp().zm(), zero.xm().zp(), - zero.xm().zm()}, - lowerEdgeStencil = interiorStencil, - upperEdgeStencil = interiorStencil; + const std::vector interpolatedUpElements = { + zero.yp(), zero.xp().yp(), zero.xm().yp(), zero.yp().zp(), zero.yp().zm()}; + const std::vector interpolatedDownElements = { + zero.ym(), zero.xp().ym(), zero.xm().ym(), zero.ym().zp(), zero.ym().zm()}; + std::set interiorStencil = { + zero, zero.xp(), zero.xm(), zero.zp(), zero.zm(), + zero.xp().zp(), zero.xp().zm(), zero.xm().zp(), zero.xm().zm()}; + std::set lowerEdgeStencil = interiorStencil; + std::set upperEdgeStencil = interiorStencil; for (const auto& i : interpolatedDownElements) { for (auto& j : interpPattern) { diff --git a/src/invert/laplace/impls/petsc3damg/petsc3damg.hxx b/src/invert/laplace/impls/petsc3damg/petsc3damg.hxx index 93dc88d768..456b85b5e6 100644 --- a/src/invert/laplace/impls/petsc3damg/petsc3damg.hxx +++ b/src/invert/laplace/impls/petsc3damg/petsc3damg.hxx @@ -27,8 +27,8 @@ **************************************************************************/ class LaplacePetsc3dAmg; -#ifndef __PETSC_LAPLACE_3DAMG_H__ -#define __PETSC_LAPLACE_3DAMG_H__ +#ifndef BOUT_PETSC_LAPLACE_3DAMG_H +#define BOUT_PETSC_LAPLACE_3DAMG_H #include "bout/build_config.hxx" #include "bout/invert_laplace.hxx" @@ -194,10 +194,10 @@ private: bool issetC = false; bool issetE = false; bool updateRequired = true; - int lower_boundary_flags; - int upper_boundary_flags; Options* opts; // Laplace Section Options Object + int lower_boundary_flags; + int upper_boundary_flags; std::string ksptype; ///< KSP solver type std::string pctype; ///< Preconditioner type @@ -216,8 +216,8 @@ private: IndexerPtr indexer; PetscMatrix operator3D; - KSP ksp; - bool kspInitialised; + KSP ksp = nullptr; + bool kspInitialised = false; PetscLib lib; // These are the implemented flags @@ -228,4 +228,4 @@ private: #endif //BOUT_HAS_PETSC -#endif //__PETSC_LAPLACE_3DAMG_H__ +#endif //BOUT_PETSC_LAPLACE_3DAMG_H diff --git a/src/invert/laplace/impls/serial_band/makefile b/src/invert/laplace/impls/serial_band/makefile deleted file mode 100644 index 2adf384942..0000000000 --- a/src/invert/laplace/impls/serial_band/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = serial_band.cxx -SOURCEH = serial_band.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/serial_band/serial_band.cxx b/src/invert/laplace/impls/serial_band/serial_band.cxx index 955e9a7ed1..4e7bb4c63f 100644 --- a/src/invert/laplace/impls/serial_band/serial_band.cxx +++ b/src/invert/laplace/impls/serial_band/serial_band.cxx @@ -99,16 +99,16 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { int xbndry = localmesh->xstart; // Width of the x boundary // If the flags to assign that only one guard cell should be used is set - if ((global_flags & INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { + if (isGlobalFlagSet(INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { xbndry = 1; } - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int ix = 0; ix < localmesh->LocalNx; ix++) { // for fixed ix,jy set a complex vector rho(z) - if (((ix < xbndry) && (inner_boundary_flags & INVERT_SET)) - || ((ncx - ix < xbndry) && (outer_boundary_flags & INVERT_SET))) { + if (((ix < xbndry) && isInnerBoundaryFlagSet(INVERT_SET)) + || ((ncx - ix < xbndry) && (isOuterBoundaryFlagSet(INVERT_SET)))) { // Use the values in x0 in the boundary rfft(x0[ix], ncz, &bk(ix, 0)); } else { @@ -247,10 +247,10 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { for (int ix = 0; ix < xbndry; ix++) { // Set zero-value. Change to zero-gradient if needed - if (!(inner_boundary_flags & (INVERT_RHS | INVERT_SET))) { + if (!isInnerBoundaryFlagSet(INVERT_RHS | INVERT_SET)) { bk1d[ix] = 0.0; } - if (!(outer_boundary_flags & (INVERT_RHS | INVERT_SET))) { + if (!isOuterBoundaryFlagSet(INVERT_RHS | INVERT_SET)) { bk1d[ncx - ix] = 0.0; } @@ -265,8 +265,8 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { // DC // Inner boundary - if (inner_boundary_flags & (INVERT_DC_GRAD + INVERT_SET) - || inner_boundary_flags & (INVERT_DC_GRAD + INVERT_RHS)) { + if (isInnerBoundaryFlagSet(INVERT_DC_GRAD + INVERT_SET) + || isInnerBoundaryFlagSet(INVERT_DC_GRAD + INVERT_RHS)) { // Zero gradient at inner boundary. 2nd-order accurate // Boundary at midpoint for (int ix = 0; ix < xbndry; ix++) { @@ -277,7 +277,7 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { A(ix, 4) = 0.; } - } else if (inner_boundary_flags & INVERT_DC_GRAD) { + } else if (isInnerBoundaryFlagSet(INVERT_DC_GRAD)) { // Zero gradient at inner boundary. 2nd-order accurate // Boundary at midpoint for (int ix = 0; ix < xbndry; ix++) { @@ -288,7 +288,7 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { A(ix, 4) = 0.; } - } else if (inner_boundary_flags & INVERT_DC_GRADPAR) { + } else if (isInnerBoundaryFlagSet(INVERT_DC_GRADPAR)) { for (int ix = 0; ix < xbndry; ix++) { A(ix, 0) = 0.; A(ix, 1) = 0.; @@ -296,7 +296,7 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { A(ix, 3) = 4. / sqrt(coords->g_22(ix + 1, jy)); A(ix, 4) = -1. / sqrt(coords->g_22(ix + 2, jy)); } - } else if (inner_boundary_flags & INVERT_DC_GRADPARINV) { + } else if (isInnerBoundaryFlagSet(INVERT_DC_GRADPARINV)) { for (int ix = 0; ix < xbndry; ix++) { A(ix, 0) = 0.; A(ix, 1) = 0.; @@ -304,7 +304,7 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { A(ix, 3) = 4. * sqrt(coords->g_22(ix + 1, jy)); A(ix, 4) = -sqrt(coords->g_22(ix + 2, jy)); } - } else if (inner_boundary_flags & INVERT_DC_LAP) { + } else if (isInnerBoundaryFlagSet(INVERT_DC_LAP)) { for (int ix = 0; ix < xbndry; ix++) { A(ix, 0) = 0.; A(ix, 1) = 0.; @@ -315,7 +315,7 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { } // Outer boundary - if (outer_boundary_flags & INVERT_DC_GRAD) { + if (isOuterBoundaryFlagSet(INVERT_DC_GRAD)) { // Zero gradient at outer boundary for (int ix = 0; ix < xbndry; ix++) { A(ncx - ix, 1) = -1.0; @@ -326,12 +326,12 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { // AC // Inner boundarySQ(kwave)*coef2 - if (inner_boundary_flags & INVERT_AC_GRAD) { + if (isInnerBoundaryFlagSet(INVERT_AC_GRAD)) { // Zero gradient at inner boundary for (int ix = 0; ix < xbndry; ix++) { A(ix, 3) = -1.0; } - } else if (inner_boundary_flags & INVERT_AC_LAP) { + } else if (isInnerBoundaryFlagSet(INVERT_AC_LAP)) { // Enforce zero laplacian for 2nd and 4th-order int ix = 1; @@ -369,12 +369,12 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { } // Outer boundary - if (outer_boundary_flags & INVERT_AC_GRAD) { + if (isOuterBoundaryFlagSet(INVERT_AC_GRAD)) { // Zero gradient at outer boundary for (int ix = 0; ix < xbndry; ix++) { A(ncx - ix, 1) = -1.0; } - } else if (outer_boundary_flags & INVERT_AC_LAP) { + } else if (isOuterBoundaryFlagSet(INVERT_AC_LAP)) { // Enforce zero laplacian for 2nd and 4th-order // NOTE: Currently ignoring XZ term and coef4 assumed zero on boundary // FIX THIS IF IT WORKS @@ -417,7 +417,7 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { // Perform inversion cband_solve(A, localmesh->LocalNx, 2, 2, bk1d); - if ((global_flags & INVERT_KX_ZERO) && (iz == 0)) { + if (isGlobalFlagSet(INVERT_KX_ZERO) && (iz == 0)) { // Set the Kx = 0, n = 0 component to zero. For now just subtract // Should do in the inversion e.g. Sherman-Morrison formula @@ -440,7 +440,7 @@ FieldPerp LaplaceSerialBand::solve(const FieldPerp& b, const FieldPerp& x0) { // Done inversion, transform back for (int ix = 0; ix <= ncx; ix++) { - if (global_flags & INVERT_ZERO_DC) { + if (isGlobalFlagSet(INVERT_ZERO_DC)) { xk(ix, 0) = 0.0; } diff --git a/src/invert/laplace/impls/serial_band/serial_band.hxx b/src/invert/laplace/impls/serial_band/serial_band.hxx index 186e716a95..d1f0fc7c65 100644 --- a/src/invert/laplace/impls/serial_band/serial_band.hxx +++ b/src/invert/laplace/impls/serial_band/serial_band.hxx @@ -26,8 +26,8 @@ class LaplaceSerialBand; -#ifndef __SERIAL_BAND_H__ -#define __SERIAL_BAND_H__ +#ifndef BOUT_SERIAL_BAND_H +#define BOUT_SERIAL_BAND_H #include "bout/build_config.hxx" #include "bout/invert_laplace.hxx" @@ -95,4 +95,4 @@ private: #endif // BOUT_USE_METRIC_3D -#endif // __SERIAL_BAND_H__ +#endif // BOUT_SERIAL_BAND_H diff --git a/src/invert/laplace/impls/serial_tri/makefile b/src/invert/laplace/impls/serial_tri/makefile deleted file mode 100644 index 771b7c9ea6..0000000000 --- a/src/invert/laplace/impls/serial_tri/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = serial_tri.cxx -SOURCEH = serial_tri.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/serial_tri/serial_tri.cxx b/src/invert/laplace/impls/serial_tri/serial_tri.cxx index e76650c751..f46a0a46e5 100644 --- a/src/invert/laplace/impls/serial_tri/serial_tri.cxx +++ b/src/invert/laplace/impls/serial_tri/serial_tri.cxx @@ -91,13 +91,13 @@ FieldPerp LaplaceSerialTri::solve(const FieldPerp& b, const FieldPerp& x0) { int inbndry = localmesh->xstart, outbndry = localmesh->xstart; // If the flags to assign that only one guard cell should be used is set - if ((global_flags & INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { + if (isGlobalFlagSet(INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { inbndry = outbndry = 1; } - if (inner_boundary_flags & INVERT_BNDRY_ONE) { + if (isInnerBoundaryFlagSet(INVERT_BNDRY_ONE)) { inbndry = 1; } - if (outer_boundary_flags & INVERT_BNDRY_ONE) { + if (isOuterBoundaryFlagSet(INVERT_BNDRY_ONE)) { outbndry = 1; } @@ -133,15 +133,15 @@ FieldPerp LaplaceSerialTri::solve(const FieldPerp& b, const FieldPerp& x0) { auto bvec = Array(ncx); auto cvec = Array(ncx); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int ix = 0; ix < ncx; ix++) { /* This for loop will set the bk (initialized by the constructor) * bk is the z fourier modes of b in z * If the INVERT_SET flag is set (meaning that x0 will be used to set the * bounadry values), */ - if (((ix < inbndry) && (inner_boundary_flags & INVERT_SET)) - || ((ncx - 1 - ix < outbndry) && (outer_boundary_flags & INVERT_SET))) { + if (((ix < inbndry) && isInnerBoundaryFlagSet(INVERT_SET)) + || ((ncx - 1 - ix < outbndry) && (isOuterBoundaryFlagSet(INVERT_SET)))) { // Use the values in x0 in the boundary // x0 is the input @@ -185,8 +185,7 @@ FieldPerp LaplaceSerialTri::solve(const FieldPerp& b, const FieldPerp& x0) { kz, // wave number (different from kz only if we are taking a part // of the z-domain [and not from 0 to 2*pi]) - kz * kwaveFactor, global_flags, inner_boundary_flags, - outer_boundary_flags, &A, &C, &D); + kz * kwaveFactor, &A, &C, &D); ///////// PERFORM INVERSION ///////// if (!localmesh->periodicX) { @@ -208,7 +207,7 @@ FieldPerp LaplaceSerialTri::solve(const FieldPerp& b, const FieldPerp& x0) { } // If the global flag is set to INVERT_KX_ZERO - if ((global_flags & INVERT_KX_ZERO) && (kz == 0)) { + if (isGlobalFlagSet(INVERT_KX_ZERO) && (kz == 0)) { dcomplex offset(0.0); for (int ix = localmesh->xstart; ix <= localmesh->xend; ix++) { offset += xk1d[ix]; @@ -228,7 +227,7 @@ FieldPerp LaplaceSerialTri::solve(const FieldPerp& b, const FieldPerp& x0) { // Done inversion, transform back for (int ix = 0; ix < ncx; ix++) { - if (global_flags & INVERT_ZERO_DC) { + if (isGlobalFlagSet(INVERT_ZERO_DC)) { xk(ix, 0) = 0.0; } diff --git a/src/invert/laplace/impls/serial_tri/serial_tri.hxx b/src/invert/laplace/impls/serial_tri/serial_tri.hxx index 05fa375de7..5b0419fa27 100644 --- a/src/invert/laplace/impls/serial_tri/serial_tri.hxx +++ b/src/invert/laplace/impls/serial_tri/serial_tri.hxx @@ -26,8 +26,8 @@ class LaplaceSerialTri; -#ifndef __SERIAL_TRI_H__ -#define __SERIAL_TRI_H__ +#ifndef BOUT_SERIAL_TRI_H +#define BOUT_SERIAL_TRI_H #include #include @@ -80,4 +80,4 @@ private: Field2D A, C, D; }; -#endif // __SERIAL_TRI_H__ +#endif // BOUT_SERIAL_TRI_H diff --git a/src/invert/laplace/impls/spt/makefile b/src/invert/laplace/impls/spt/makefile deleted file mode 100644 index 41d0b54d64..0000000000 --- a/src/invert/laplace/impls/spt/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = spt.cxx -SOURCEH = spt.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplace/impls/spt/spt.cxx b/src/invert/laplace/impls/spt/spt.cxx index 92959e1194..2e4c844c94 100644 --- a/src/invert/laplace/impls/spt/spt.cxx +++ b/src/invert/laplace/impls/spt/spt.cxx @@ -65,10 +65,9 @@ LaplaceSPT::LaplaceSPT(Options* opt, const CELL_LOC loc, Mesh* mesh_in, ye = localmesh->LocalNy - 1; // Contains upper boundary } - alldata = new SPT_data[ye - ys + 1]; - alldata -= ys; // Re-number indices to start at ys + alldata.reallocate(ye - ys + 1); for (int jy = ys; jy <= ye; jy++) { - alldata[jy].comm_tag = SPT_DATA + jy; // Give each one a different tag + alldata[jy - ys].comm_tag = SPT_DATA + jy; // Give each one a different tag } // Temporary array for taking FFTs @@ -76,11 +75,6 @@ LaplaceSPT::LaplaceSPT(Options* opt, const CELL_LOC loc, Mesh* mesh_in, dc1d.reallocate(ncz / 2 + 1); } -LaplaceSPT::~LaplaceSPT() { - alldata += ys; // Return to index from 0 - delete[] alldata; -} - FieldPerp LaplaceSPT::solve(const FieldPerp& b) { return solve(b, b); } FieldPerp LaplaceSPT::solve(const FieldPerp& b, const FieldPerp& x0) { @@ -90,15 +84,15 @@ FieldPerp LaplaceSPT::solve(const FieldPerp& b, const FieldPerp& x0) { FieldPerp x{emptyFrom(b)}; - if ((inner_boundary_flags & INVERT_SET) || (outer_boundary_flags & INVERT_SET)) { + if (isInnerBoundaryFlagSet(INVERT_SET) || isOuterBoundaryFlagSet(INVERT_SET)) { FieldPerp bs = copy(b); int xbndry = localmesh->xstart; // If the flags to assign that only one guard cell should be used is set - if ((global_flags & INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { + if (isGlobalFlagSet(INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { xbndry = 1; } - if ((inner_boundary_flags & INVERT_SET) && localmesh->firstX()) { + if (isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) { // Copy x0 inner boundary into bs for (int ix = 0; ix < xbndry; ix++) { for (int iz = 0; iz < localmesh->LocalNz; iz++) { @@ -106,7 +100,7 @@ FieldPerp LaplaceSPT::solve(const FieldPerp& b, const FieldPerp& x0) { } } } - if ((outer_boundary_flags & INVERT_SET) && localmesh->lastX()) { + if (isOuterBoundaryFlagSetOnLastX(INVERT_SET)) { // Copy x0 outer boundary into bs for (int ix = localmesh->LocalNx - 1; ix >= localmesh->LocalNx - xbndry; ix--) { for (int iz = 0; iz < localmesh->LocalNz; iz++) { @@ -141,29 +135,29 @@ Field3D LaplaceSPT::solve(const Field3D& b) { for (int jy = ys; jy <= ye; jy++) { // And start another one going - start(sliceXZ(b, jy), alldata[jy]); + start(sliceXZ(b, jy), alldata[jy - ys]); // Move each calculation along one processor for (int jy2 = ys; jy2 < jy; jy2++) { - next(alldata[jy2]); + next(alldata[jy2 - ys]); } } bool running = true; - do { + while (running) { // Move each calculation along until the last one is finished - for (int jy = ys; jy <= ye; jy++) { - running = next(alldata[jy]) == 0; + for (auto& data : alldata) { + running = next(data) == 0; } - } while (running); + } FieldPerp xperp(localmesh); xperp.setLocation(location); xperp.allocate(); // All calculations finished. Get result - for (int jy = ys; jy <= ye; jy++) { - finish(alldata[jy], xperp); + for (auto& data : alldata) { + finish(data, xperp); x = xperp; } @@ -173,17 +167,17 @@ Field3D LaplaceSPT::solve(const Field3D& b) { Field3D LaplaceSPT::solve(const Field3D& b, const Field3D& x0) { ASSERT1(localmesh == b.getMesh() && localmesh == x0.getMesh()); - if (((inner_boundary_flags & INVERT_SET) && localmesh->firstX()) - || ((outer_boundary_flags & INVERT_SET) && localmesh->lastX())) { + if ((isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) + || isOuterBoundaryFlagSetOnLastX(INVERT_SET)) { Field3D bs = copy(b); int xbndry = localmesh->xstart; // If the flags to assign that only one guard cell should be used is set - if ((global_flags & INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { + if (isGlobalFlagSet(INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { xbndry = 1; } - if ((inner_boundary_flags & INVERT_SET) && localmesh->firstX()) { + if (isInnerBoundaryFlagSetOnFirstX(INVERT_SET)) { // Copy x0 inner boundary into bs for (int ix = 0; ix < xbndry; ix++) { for (int iy = 0; iy < localmesh->LocalNy; iy++) { @@ -193,7 +187,7 @@ Field3D LaplaceSPT::solve(const Field3D& b, const Field3D& x0) { } } } - if ((outer_boundary_flags & INVERT_SET) && localmesh->lastX()) { + if (isOuterBoundaryFlagSetOnLastX(INVERT_SET)) { // Copy x0 outer boundary into bs for (int ix = localmesh->LocalNx - 1; ix >= localmesh->LocalNx - xbndry; ix--) { for (int iy = 0; iy < localmesh->LocalNy; iy++) { @@ -323,15 +317,14 @@ int LaplaceSPT::start(const FieldPerp& b, SPT_data& data) { /// Set matrix elements for (int kz = 0; kz <= maxmode; kz++) { tridagMatrix(&data.avec(kz, 0), &data.bvec(kz, 0), &data.cvec(kz, 0), &data.bk(kz, 0), - data.jy, kz, kz * kwaveFactor, global_flags, inner_boundary_flags, - outer_boundary_flags, &Acoef, &Ccoef, &Dcoef); + data.jy, kz, kz * kwaveFactor, &Acoef, &Ccoef, &Dcoef); } data.proc = 0; //< Starts at processor 0 data.dir = 1; if (localmesh->firstX()) { - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int kz = 0; kz <= maxmode; kz++) { dcomplex bet, u0; // Start tridiagonal solve @@ -382,7 +375,7 @@ int LaplaceSPT::next(SPT_data& data) { if (localmesh->lastX()) { // Last processor, turn-around - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int kz = 0; kz <= maxmode; kz++) { dcomplex bet, u0; dcomplex gp, up; @@ -409,7 +402,7 @@ int LaplaceSPT::next(SPT_data& data) { } else if (data.dir > 0) { // In the middle of X, forward direction - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int kz = 0; kz <= maxmode; kz++) { dcomplex bet, u0; bet = dcomplex(data.buffer[4 * kz], data.buffer[4 * kz + 1]); @@ -429,7 +422,7 @@ int LaplaceSPT::next(SPT_data& data) { } else if (localmesh->firstX()) { // Back to the start - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int kz = 0; kz <= maxmode; kz++) { dcomplex gp, up; gp = dcomplex(data.buffer[4 * kz], data.buffer[4 * kz + 1]); @@ -441,7 +434,7 @@ int LaplaceSPT::next(SPT_data& data) { } else { // Middle of X, back-substitution stage - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int kz = 0; kz <= maxmode; kz++) { dcomplex gp = dcomplex(data.buffer[4 * kz], data.buffer[4 * kz + 1]); dcomplex up = dcomplex(data.buffer[4 * kz + 2], data.buffer[4 * kz + 3]); @@ -516,7 +509,7 @@ void LaplaceSPT::finish(SPT_data& data, FieldPerp& x) { dc1d[kz] = 0.0; } - if (global_flags & INVERT_ZERO_DC) { + if (isGlobalFlagSet(INVERT_ZERO_DC)) { dc1d[0] = 0.0; } diff --git a/src/invert/laplace/impls/spt/spt.hxx b/src/invert/laplace/impls/spt/spt.hxx index 27e9c8100c..a9d5b2583f 100644 --- a/src/invert/laplace/impls/spt/spt.hxx +++ b/src/invert/laplace/impls/spt/spt.hxx @@ -38,8 +38,8 @@ class LaplaceSPT; -#ifndef __SPT_H__ -#define __SPT_H__ +#ifndef BOUT_SPT_H +#define BOUT_SPT_H #include #include @@ -69,7 +69,6 @@ class LaplaceSPT : public Laplacian { public: LaplaceSPT(Options* opt = nullptr, const CELL_LOC = CELL_CENTRE, Mesh* mesh_in = nullptr, Solver* solver = nullptr); - ~LaplaceSPT(); using Laplacian::setCoefA; void setCoefA(const Field2D& val) override { @@ -106,17 +105,15 @@ public: Field3D solve(const Field3D& b, const Field3D& x0) override; private: - enum { SPT_DATA = 1123 }; ///< 'magic' number for SPT MPI messages + constexpr static int SPT_DATA = 1123; ///< 'magic' number for SPT MPI messages Field2D Acoef, Ccoef, Dcoef; /// Data structure for SPT algorithm struct SPT_data { - SPT_data() : comm_tag(SPT_DATA) {} void allocate(int mm, int nx); // Allocates memory - ~SPT_data(){}; // Free memory - int jy; ///< Y index + int jy = 0; ///< Y index Matrix bk; ///< b vector in Fourier space Matrix xk; @@ -125,19 +122,19 @@ private: Matrix avec, bvec, cvec; ///< Diagonal bands of matrix - int proc; // Which processor has this reached? - int dir; // Which direction is it going? + int proc = 0; // Which processor has this reached? + int dir = 1; // Which direction is it going? - comm_handle recv_handle; // Handle for receives + comm_handle recv_handle = nullptr; // Handle for receives - int comm_tag; // Tag for communication + int comm_tag = SPT_DATA; // Tag for communication Array buffer; }; int ys, ye; // Range of Y indices SPT_data slicedata; // Used to solve for a single FieldPerp - SPT_data* alldata; // Used to solve a Field3D + Array alldata; // Used to solve a Field3D Array dc1d; ///< 1D in Z for taking FFTs @@ -159,4 +156,4 @@ namespace { RegisterLaplace registerlaplacespt(LAPLACE_SPT); } // namespace -#endif // __SPT_H__ +#endif // BOUT_SPT_H diff --git a/src/invert/laplace/invert_laplace.cxx b/src/invert/laplace/invert_laplace.cxx index dc3d1a3c3f..4032499781 100644 --- a/src/invert/laplace/invert_laplace.cxx +++ b/src/invert/laplace/invert_laplace.cxx @@ -424,20 +424,16 @@ void Laplacian::tridagCoefs(int jx, int jy, BoutReal kwave, dcomplex& a, dcomple #if BOUT_USE_METRIC_3D void Laplacian::tridagMatrix(dcomplex* /*avec*/, dcomplex* /*bvec*/, dcomplex* /*cvec*/, dcomplex* /*bk*/, int /*jy*/, int /*kz*/, BoutReal /*kwave*/, - int /*global_flags*/, int /*inner_boundary_flags*/, - int /*outer_boundary_flags*/, const Field2D* /*a*/, - const Field2D* /*c1coef*/, const Field2D* /*c2coef*/, - const Field2D* /*d*/, bool /*includeguards*/, - bool /*zperiodic*/) { + const Field2D* /*a*/, const Field2D* /*c1coef*/, + const Field2D* /*c2coef*/, const Field2D* /*d*/, + bool /*includeguards*/, bool /*zperiodic*/) { throw BoutException("Error: tridagMatrix does not yet work with 3D metric."); } #else void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dcomplex* bk, - int jy, int kz, BoutReal kwave, int global_flags, - int inner_boundary_flags, int outer_boundary_flags, - const Field2D* a, const Field2D* c1coef, - const Field2D* c2coef, const Field2D* d, bool includeguards, - bool zperiodic) { + int jy, int kz, BoutReal kwave, const Field2D* a, + const Field2D* c1coef, const Field2D* c2coef, + const Field2D* d, bool includeguards, bool zperiodic) { ASSERT1(a->getLocation() == location); ASSERT1(c1coef->getLocation() == location); ASSERT1(c2coef->getLocation() == location); @@ -469,13 +465,13 @@ void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dco int inbndry = localmesh->xstart, outbndry = localmesh->xstart; // If the flags to assign that only one guard cell should be used is set - if ((global_flags & INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { + if (isGlobalFlagSet(INVERT_BOTH_BNDRY_ONE) || (localmesh->xstart < 2)) { inbndry = outbndry = 1; } - if (inner_boundary_flags & INVERT_BNDRY_ONE) { + if (isInnerBoundaryFlagSet(INVERT_BNDRY_ONE)) { inbndry = 1; } - if (outer_boundary_flags & INVERT_BNDRY_ONE) { + if (isOuterBoundaryFlagSet(INVERT_BNDRY_ONE)) { outbndry = 1; } @@ -497,7 +493,7 @@ void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dco // If no user specified value is set on inner boundary, set the first // element in b (in the equation AX=b) to 0 - if (!(inner_boundary_flags & (INVERT_RHS | INVERT_SET))) { + if (!isInnerBoundaryFlagSet(INVERT_RHS | INVERT_SET)) { for (int ix = 0; ix < inbndry; ix++) { bk[ix] = 0.; } @@ -506,34 +502,35 @@ void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dco // DC i.e. kz = 0 (the offset mode) if (kz == 0) { - if (inner_boundary_flags & INVERT_DC_GRAD - && (inner_boundary_flags & INVERT_SET || inner_boundary_flags & INVERT_RHS)) { + if (isInnerBoundaryFlagSet(INVERT_DC_GRAD) + && (isInnerBoundaryFlagSet(INVERT_SET) + || isInnerBoundaryFlagSet(INVERT_RHS))) { // Zero gradient at inner boundary for (int ix = 0; ix < inbndry; ix++) { avec[ix] = 0.; bvec[ix] = -1. / sqrt(coords->g_11(ix, jy)) / coords->dx(ix, jy); cvec[ix] = 1. / sqrt(coords->g_11(ix, jy)) / coords->dx(ix, jy); } - } else if (inner_boundary_flags & INVERT_DC_GRAD) { + } else if (isInnerBoundaryFlagSet(INVERT_DC_GRAD)) { // Zero gradient at inner boundary for (int ix = 0; ix < inbndry; ix++) { avec[ix] = 0.; bvec[ix] = -1.; cvec[ix] = 1.; } - } else if (inner_boundary_flags & INVERT_DC_GRADPAR) { + } else if (isInnerBoundaryFlagSet(INVERT_DC_GRADPAR)) { for (int ix = 0; ix < inbndry; ix++) { avec[ix] = 0.0; bvec[ix] = 1.0 / sqrt(coords->g_22(ix, jy)); cvec[ix] = -1.0 / sqrt(coords->g_22(ix + 1, jy)); } - } else if (inner_boundary_flags & INVERT_DC_GRADPARINV) { + } else if (isInnerBoundaryFlagSet(INVERT_DC_GRADPARINV)) { for (int ix = 0; ix < inbndry; ix++) { avec[ix] = 0.0; bvec[ix] = sqrt(coords->g_22(ix, jy)); cvec[ix] = -sqrt(coords->g_22(ix + 1, jy)); } - } else if (inner_boundary_flags & INVERT_DC_LAP) { + } else if (isInnerBoundaryFlagSet(INVERT_DC_LAP)) { // Decaying boundary conditions BoutReal k = 0.0; if (a != nullptr) { @@ -548,7 +545,7 @@ void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dco bvec[ix] = 1.; cvec[ix] = -exp(-k * coords->dx(ix, jy) / sqrt(coords->g11(ix, jy))); } - } else if (inner_boundary_flags & INVERT_IN_CYLINDER) { + } else if (isInnerBoundaryFlagSet(INVERT_IN_CYLINDER)) { // Condition for inner radial boundary for cylindrical coordinates /* Explanation: * The discrete fourier transform is defined as @@ -602,8 +599,9 @@ void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dco // AC i.e. kz =/= 0 (all other modes than the offset mode) else { - if (inner_boundary_flags & INVERT_AC_GRAD - && (inner_boundary_flags & INVERT_SET || inner_boundary_flags & INVERT_RHS)) { + if (isInnerBoundaryFlagSet(INVERT_AC_GRAD) + && (isInnerBoundaryFlagSet(INVERT_SET) + || isInnerBoundaryFlagSet(INVERT_RHS))) { // Zero gradient at inner boundary for (int ix = 0; ix < inbndry; ix++) { avec[ix] = dcomplex(0., 0.); @@ -611,14 +609,14 @@ void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dco dcomplex(-1., 0.) / sqrt(coords->g_11(ix, jy)) / coords->dx(ix, jy); cvec[ix] = dcomplex(1., 0.) / sqrt(coords->g_11(ix, jy)) / coords->dx(ix, jy); } - } else if (inner_boundary_flags & INVERT_AC_GRAD) { + } else if (isInnerBoundaryFlagSet(INVERT_AC_GRAD)) { // Zero gradient at inner boundary for (int ix = 0; ix < inbndry; ix++) { avec[ix] = dcomplex(0., 0.); bvec[ix] = dcomplex(-1., 0.); cvec[ix] = dcomplex(1., 0.); } - } else if (inner_boundary_flags & INVERT_AC_LAP) { + } else if (isInnerBoundaryFlagSet(INVERT_AC_LAP)) { // Use decaying zero-Laplacian solution in the boundary for (int ix = 0; ix < inbndry; ix++) { avec[ix] = 0.0; @@ -626,9 +624,9 @@ void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dco cvec[ix] = -exp(-1.0 * sqrt(coords->g33(ix, jy) / coords->g11(ix, jy)) * kwave * coords->dx(ix, jy)); } - } else if (inner_boundary_flags & INVERT_IN_CYLINDER) { + } else if (isInnerBoundaryFlagSet(INVERT_IN_CYLINDER)) { // Condition for inner radial boundary for cylindrical coordinates - // Explanation under "if (inner_boundary_flags & INVERT_IN_CYLINDER)" + // Explanation under "if (isInnerBoundaryFlagSet(INVERT_IN_CYLINDER))" for (int ix = 0; ix < inbndry; ix++) { avec[ix] = 0.; bvec[ix] = 1.; @@ -655,7 +653,7 @@ void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dco // If no user specified value is set on outer boundary, set the last // element in b (in the equation AX=b) to 0 - if (!(outer_boundary_flags & (INVERT_RHS | INVERT_SET))) { + if (!isOuterBoundaryFlagSet(INVERT_RHS | INVERT_SET)) { for (int ix = 0; ix < outbndry; ix++) { bk[ncx - ix] = 0.; } @@ -664,36 +662,37 @@ void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dco // DC i.e. kz = 0 (the offset mode) if (kz == 0) { - if (outer_boundary_flags & INVERT_DC_GRAD - && (outer_boundary_flags & INVERT_SET || outer_boundary_flags & INVERT_RHS)) { + if (isOuterBoundaryFlagSet(INVERT_DC_GRAD) + && (isOuterBoundaryFlagSet(INVERT_SET) + || isOuterBoundaryFlagSet(INVERT_RHS))) { // Zero gradient at outer boundary for (int ix = 0; ix < outbndry; ix++) { - avec[ncx - ix] = dcomplex(-1., 0.) / sqrt(coords->g_11(ncx - ix, jy)) - / coords->dx(ncx - ix, jy); - bvec[ncx - ix] = dcomplex(1., 0.) / sqrt(coords->g_11(ncx - ix, jy)) - / coords->dx(ncx - ix, jy); + avec[ncx - ix] = dcomplex(-1., 0.) / sqrt(coords->g_11(xe - ix, jy)) + / coords->dx(xe - ix, jy); + bvec[ncx - ix] = dcomplex(1., 0.) / sqrt(coords->g_11(xe - ix, jy)) + / coords->dx(xe - ix, jy); cvec[ncx - ix] = dcomplex(0., 0.); } - } else if (outer_boundary_flags & INVERT_DC_GRAD) { + } else if (isOuterBoundaryFlagSet(INVERT_DC_GRAD)) { // Zero gradient at outer boundary for (int ix = 0; ix < outbndry; ix++) { avec[ncx - ix] = dcomplex(1., 0.); bvec[ncx - ix] = dcomplex(-1., 0.); cvec[ncx - ix] = dcomplex(0., 0.); } - } else if (inner_boundary_flags & INVERT_DC_GRADPAR) { + } else if (isOuterBoundaryFlagSet(INVERT_DC_GRADPAR)) { for (int ix = 0; ix < inbndry; ix++) { - avec[ncx - ix] = 1.0 / sqrt(coords->g_22(ncx - ix + 1, jy)); - bvec[ncx - ix] = -1.0 / sqrt(coords->g_22(ncx - ix, jy)); + avec[ncx - ix] = 1.0 / sqrt(coords->g_22(xe - ix - 1, jy)); + bvec[ncx - ix] = -1.0 / sqrt(coords->g_22(xe - ix, jy)); cvec[ncx - ix] = 0.0; } - } else if (inner_boundary_flags & INVERT_DC_GRADPARINV) { + } else if (isOuterBoundaryFlagSet(INVERT_DC_GRADPARINV)) { for (int ix = 0; ix < inbndry; ix++) { - avec[ncx - ix] = sqrt(coords->g_22(ncx - ix - 1, jy)); - bvec[ncx - ix] = -sqrt(coords->g_22(ncx - ix, jy)); + avec[ncx - ix] = sqrt(coords->g_22(xe - ix - 1, jy)); + bvec[ncx - ix] = -sqrt(coords->g_22(xe - ix, jy)); cvec[ncx - ix] = 0.0; } - } else if (inner_boundary_flags & INVERT_DC_LAP) { + } else if (isOuterBoundaryFlagSet(INVERT_DC_LAP)) { // Decaying boundary conditions BoutReal k = 0.0; if (a != nullptr) { @@ -707,7 +706,7 @@ void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dco cvec[ncx - ix] = 0.; bvec[ncx - ix] = 1.; avec[ncx - ix] = - -exp(-k * coords->dx(ncx - ix, jy) / sqrt(coords->g11(ncx - ix, jy))); + -exp(-k * coords->dx(xe - ix, jy) / sqrt(coords->g11(xe - ix, jy))); } } else { // Order 2 dirichlet BC (boundary half between points) @@ -722,24 +721,25 @@ void Laplacian::tridagMatrix(dcomplex* avec, dcomplex* bvec, dcomplex* cvec, dco // AC i.e. kz =/= 0 (all other modes than the offset mode) else { - if (outer_boundary_flags & INVERT_AC_GRAD - && (outer_boundary_flags & INVERT_SET || outer_boundary_flags & INVERT_RHS)) { + if (isOuterBoundaryFlagSet(INVERT_AC_GRAD) + && (isOuterBoundaryFlagSet(INVERT_SET) + || isOuterBoundaryFlagSet(INVERT_RHS))) { // Zero gradient at outer boundary for (int ix = 0; ix < outbndry; ix++) { - avec[ncx - ix] = dcomplex(-1., 0.) / sqrt(coords->g_11(ncx - ix, jy)) - / coords->dx(ncx - ix, jy); - bvec[ncx - ix] = dcomplex(1., 0.) / sqrt(coords->g_11(ncx - ix, jy)) - / coords->dx(ncx - ix, jy); + avec[ncx - ix] = dcomplex(-1., 0.) / sqrt(coords->g_11(xe - ix, jy)) + / coords->dx(xe - ix, jy); + bvec[ncx - ix] = dcomplex(1., 0.) / sqrt(coords->g_11(xe - ix, jy)) + / coords->dx(xe - ix, jy); cvec[ncx - ix] = dcomplex(0., 0.); } - } else if (outer_boundary_flags & INVERT_AC_GRAD) { + } else if (isOuterBoundaryFlagSet(INVERT_AC_GRAD)) { // Zero gradient at outer boundary for (int ix = 0; ix < outbndry; ix++) { avec[ncx - ix] = dcomplex(1., 0.); bvec[ncx - ix] = dcomplex(-1., 0.); cvec[ncx - ix] = dcomplex(0., 0.); } - } else if (outer_boundary_flags & INVERT_AC_LAP) { + } else if (isOuterBoundaryFlagSet(INVERT_AC_LAP)) { // Use decaying zero-Laplacian solution in the boundary for (int ix = 0; ix < outbndry; ix++) { avec[ncx - ix] = @@ -782,9 +782,10 @@ void Laplacian::savePerformance(Solver& solver, const std::string& name) { solver.addMonitor(&monitor, Solver::BACK); } -int Laplacian::LaplacianMonitor::call(MAYBE_UNUSED(Solver* solver), - MAYBE_UNUSED(BoutReal time), MAYBE_UNUSED(int iter), - MAYBE_UNUSED(int nout)) { +int Laplacian::LaplacianMonitor::call([[maybe_unused]] Solver* solver, + [[maybe_unused]] BoutReal time, + [[maybe_unused]] int iter, + [[maybe_unused]] int nout) { // Nothing to do, values are always calculated return 0; } @@ -794,6 +795,13 @@ void Laplacian::LaplacianMonitor::outputVars(Options& output_options, laplacian->outputVars(output_options, time_dimension); } +bool Laplacian::isInnerBoundaryFlagSetOnFirstX(int flag) const { + return isInnerBoundaryFlagSet(flag) and localmesh->firstX(); +} +bool Laplacian::isOuterBoundaryFlagSetOnLastX(int flag) const { + return isOuterBoundaryFlagSet(flag) and localmesh->lastX(); +} + /********************************************************************************** * LEGACY INTERFACE * @@ -805,7 +813,3 @@ void laplace_tridag_coefs(int jx, int jy, int jz, dcomplex& a, dcomplex& b, dcom const Field2D* ccoef, const Field2D* d, CELL_LOC loc) { Laplacian::defaultInstance()->tridagCoefs(jx, jy, jz, a, b, c, ccoef, d, loc); } -constexpr decltype(LaplaceFactory::type_name) LaplaceFactory::type_name; -constexpr decltype(LaplaceFactory::section_name) LaplaceFactory::section_name; -constexpr decltype(LaplaceFactory::option_name) LaplaceFactory::option_name; -constexpr decltype(LaplaceFactory::default_type) LaplaceFactory::default_type; diff --git a/src/invert/laplace/makefile b/src/invert/laplace/makefile deleted file mode 100644 index baa2f806bc..0000000000 --- a/src/invert/laplace/makefile +++ /dev/null @@ -1,9 +0,0 @@ - -BOUT_TOP = ../../.. - -DIRS = impls -SOURCEC = invert_laplace.cxx -SOURCEH = invert_laplace.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplacexy/makefile b/src/invert/laplacexy/makefile deleted file mode 100644 index 241d03c302..0000000000 --- a/src/invert/laplacexy/makefile +++ /dev/null @@ -1,7 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = laplacexy.cxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplacexy2/makefile b/src/invert/laplacexy2/makefile deleted file mode 100644 index c785581f2f..0000000000 --- a/src/invert/laplacexy2/makefile +++ /dev/null @@ -1,7 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = laplacexy2.cxx laplacexy2_hypre.cxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplacexz/impls/cyclic/makefile b/src/invert/laplacexz/impls/cyclic/makefile deleted file mode 100644 index da426eb84a..0000000000 --- a/src/invert/laplacexz/impls/cyclic/makefile +++ /dev/null @@ -1,7 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = laplacexz-cyclic.cxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplacexz/impls/makefile b/src/invert/laplacexz/impls/makefile deleted file mode 100644 index cf12301782..0000000000 --- a/src/invert/laplacexz/impls/makefile +++ /dev/null @@ -1,7 +0,0 @@ - -BOUT_TOP = ../../../.. - -DIRS = cyclic petsc -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplacexz/impls/petsc/laplacexz-petsc.hxx b/src/invert/laplacexz/impls/petsc/laplacexz-petsc.hxx index 47967390f9..7e15be5a34 100644 --- a/src/invert/laplacexz/impls/petsc/laplacexz-petsc.hxx +++ b/src/invert/laplacexz/impls/petsc/laplacexz-petsc.hxx @@ -6,8 +6,8 @@ class LaplaceXZpetsc; -#ifndef __LAPLACEXZ_PETSC_H__ -#define __LAPLACEXZ_PETSC_H__ +#ifndef BOUT_LAPLACEXZ_PETSC_H +#define BOUT_LAPLACEXZ_PETSC_H #include "bout/build_config.hxx" #include "bout/invert/laplacexz.hxx" @@ -73,4 +73,4 @@ private: }; #endif // BOUT_HAS_PETSC -#endif // __LAPLACEXZ_PETSC_H__ +#endif // BOUT_LAPLACEXZ_PETSC_H diff --git a/src/invert/laplacexz/impls/petsc/makefile b/src/invert/laplacexz/impls/petsc/makefile deleted file mode 100644 index d6826dd574..0000000000 --- a/src/invert/laplacexz/impls/petsc/makefile +++ /dev/null @@ -1,7 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = laplacexz-petsc.cxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/laplacexz/laplacexz.cxx b/src/invert/laplacexz/laplacexz.cxx index a2b99280e6..d064f62104 100644 --- a/src/invert/laplacexz/laplacexz.cxx +++ b/src/invert/laplacexz/laplacexz.cxx @@ -5,8 +5,3 @@ // DO NOT REMOVE: ensures linker keeps all symbols in this TU void LaplaceXZFactory::ensureRegistered() {} - -constexpr decltype(LaplaceXZFactory::type_name) LaplaceXZFactory::type_name; -constexpr decltype(LaplaceXZFactory::section_name) LaplaceXZFactory::section_name; -constexpr decltype(LaplaceXZFactory::option_name) LaplaceXZFactory::option_name; -constexpr decltype(LaplaceXZFactory::default_type) LaplaceXZFactory::default_type; diff --git a/src/invert/laplacexz/makefile b/src/invert/laplacexz/makefile deleted file mode 100644 index 42022dd0b6..0000000000 --- a/src/invert/laplacexz/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../.. - -DIRS = impls -SOURCEC = laplacexz.cxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/makefile b/src/invert/makefile deleted file mode 100644 index 7deae4cdc5..0000000000 --- a/src/invert/makefile +++ /dev/null @@ -1,9 +0,0 @@ - -BOUT_TOP = ../.. - -DIRS = parderiv pardiv laplace laplacexy laplacexz laplacexy2 -SOURCEC = fft_fftw.cxx lapack_routines.cxx -SOURCEH = fft.hxx invert_parderiv.hxx lapack_routines.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/parderiv/impls/cyclic/cyclic.hxx b/src/invert/parderiv/impls/cyclic/cyclic.hxx index 0c581adc52..6493a3b945 100644 --- a/src/invert/parderiv/impls/cyclic/cyclic.hxx +++ b/src/invert/parderiv/impls/cyclic/cyclic.hxx @@ -39,8 +39,8 @@ * ************************************************************************/ -#ifndef __INV_PAR_CR_H__ -#define __INV_PAR_CR_H__ +#ifndef BOUT_INV_PAR_CR_H +#define BOUT_INV_PAR_CR_H #include "bout/build_config.hxx" #include "bout/invert_parderiv.hxx" @@ -110,4 +110,4 @@ RegisterInvertPar registerinvertparcyclic{PARDERIVCYCLIC}; #endif // BOUT_USE_METRIC_3D -#endif // __INV_PAR_CR_H__ +#endif // BOUT_INV_PAR_CR_H diff --git a/src/invert/parderiv/impls/cyclic/makefile b/src/invert/parderiv/impls/cyclic/makefile deleted file mode 100644 index 7617df09d5..0000000000 --- a/src/invert/parderiv/impls/cyclic/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = cyclic.cxx -SOURCEH = cyclic.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/parderiv/impls/makefile b/src/invert/parderiv/impls/makefile deleted file mode 100644 index 2f417f8106..0000000000 --- a/src/invert/parderiv/impls/makefile +++ /dev/null @@ -1,7 +0,0 @@ - -BOUT_TOP = ../../../.. - -DIRS = cyclic -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/parderiv/invert_parderiv.cxx b/src/invert/parderiv/invert_parderiv.cxx index bc8ad8669f..e14c0ee1d2 100644 --- a/src/invert/parderiv/invert_parderiv.cxx +++ b/src/invert/parderiv/invert_parderiv.cxx @@ -39,7 +39,3 @@ const Field2D InvertPar::solve(const Field2D& f) { // DO NOT REMOVE: ensures linker keeps all symbols in this TU void InvertParFactory::ensureRegistered() {} -constexpr decltype(InvertParFactory::type_name) InvertParFactory::type_name; -constexpr decltype(InvertParFactory::section_name) InvertParFactory::section_name; -constexpr decltype(InvertParFactory::option_name) InvertParFactory::option_name; -constexpr decltype(InvertParFactory::default_type) InvertParFactory::default_type; diff --git a/src/invert/parderiv/makefile b/src/invert/parderiv/makefile deleted file mode 100644 index 93bad386bc..0000000000 --- a/src/invert/parderiv/makefile +++ /dev/null @@ -1,9 +0,0 @@ - -BOUT_TOP = ../../.. - -DIRS = impls -SOURCEC = invert_parderiv.cxx -SOURCEH = invert_parderiv.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/pardiv/impls/cyclic/makefile b/src/invert/pardiv/impls/cyclic/makefile deleted file mode 100644 index 0fa26267b9..0000000000 --- a/src/invert/pardiv/impls/cyclic/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../.. - -SOURCEC = pardiv_cyclic.cxx -SOURCEH = pardiv_cyclic.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/pardiv/impls/makefile b/src/invert/pardiv/impls/makefile deleted file mode 100644 index 2f417f8106..0000000000 --- a/src/invert/pardiv/impls/makefile +++ /dev/null @@ -1,7 +0,0 @@ - -BOUT_TOP = ../../../.. - -DIRS = cyclic -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/invert/pardiv/invert_pardiv.cxx b/src/invert/pardiv/invert_pardiv.cxx index d05b594aa1..30e421edd8 100644 --- a/src/invert/pardiv/invert_pardiv.cxx +++ b/src/invert/pardiv/invert_pardiv.cxx @@ -39,7 +39,3 @@ Field2D InvertParDiv::solve(const Field2D& f) { // DO NOT REMOVE: ensures linker keeps all symbols in this TU void InvertParDivFactory::ensureRegistered() {} -constexpr decltype(InvertParDivFactory::type_name) InvertParDivFactory::type_name; -constexpr decltype(InvertParDivFactory::section_name) InvertParDivFactory::section_name; -constexpr decltype(InvertParDivFactory::option_name) InvertParDivFactory::option_name; -constexpr decltype(InvertParDivFactory::default_type) InvertParDivFactory::default_type; diff --git a/src/invert/pardiv/makefile b/src/invert/pardiv/makefile deleted file mode 100644 index 0fe293644b..0000000000 --- a/src/invert/pardiv/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../.. - -DIRS = impls -SOURCEC = invert_pardiv.cxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/makefile.in b/src/makefile.in deleted file mode 100644 index 136f5b68c9..0000000000 --- a/src/makefile.in +++ /dev/null @@ -1,96 +0,0 @@ - -BOUT_TOP = .. - -DIRS = field invert mesh physics solver sys fmt - -SOURCEC = bout++.cxx bout++-time.cxx -SOURCEH = bout.hxx -CXXFLAGS += -DMD5SUM=$(CHECKSUM) -DBOUT_REVISION="$(BOUT_REVISION)" -TARGET ?= lib - -# Checksum passed to bout++.cxx -CHECKSUM := $(shell cat $(foreach DIR,$(DIRS),$(wildcard $(DIR)/*.cxx $(DIR)/*.hxx)) | md5sum | head -c 32 ) - -# Git revision passed to bout++.cxx -BOUT_REVISION := $(shell git rev-parse HEAD 2> /dev/null || hg id -n 2> /dev/null || { echo "Unknown"; } ) - -# From the legacy build script: -# This is a little obscure, so here is an explanation: -# the first 'all: initial_message' sets the prerequisite 'inital_message' -# to be the first one called -all: initial_message - -# Then the config file is included, which has all the other -# prerequisites for 'all' -include $(BOUT_TOP)/make.config - -# Rebuild bout++-time to get the correct time of the build - but only if -# any other file was rebuild -bout++-time.o: $(BOUT_LIB_PATH)/.last.o.file | $(DIRS) bout++.o - -# The recipie could be removed, as it only catches the case of -# out-of-date make.config -# The rest is needed to tell make that .last.o.file will be created -$(BOUT_LIB_PATH)/.last.o.file: | $(DIRS) - @test -f $@ || \ - echo "make.config is out of date - run ./configure" - @test -f $@ || \ - exit 1 - -libfast: | @LIB_TO_BUILD@ - -$(BOUT_LIB_PATH)/libbout++.a: bout++-time.o - @echo "Recreating libbout++.a" - @rm -f $(LIB_A) - @$(AR) $(ARFLAGS) $(LIB_A) $(shell find $(BOUT_TOP)/src -name \*.o -type f -print 2> /dev/null) || rm -f $(LIB_A) - @touch .libfast - @#$(RANLIB) $(LIB) - @@STATIC_EXTRA@ - -$(BOUT_LIB_PATH)/libbout++.so: bout++-time.o - @echo "Creating libbout++.so" - @echo $(BOUT_FLAGS) | grep -qi pic || (echo "not compiled with PIC support - reconfigure with --enable-shared" ;exit 1) - @$(RM) $(BOUT_LIB_PATH)/*.so* - @$(CXX) -shared -Wl,-soname,libbout++.so.$(BOUT_VERSION) -o $(LIB_SO).$(BOUT_VERSION) \ - $(shell find $(BOUT_TOP)/src -name \*.o -type f -print 2> /dev/null) \ - $(LDFLAGS) - @$(CXX) -shared -Wl,-soname,libpvode.so.1.0.0 -o $(BOUT_LIB_PATH)/libpvode_.so \ - -L $(BOUT_LIB_PATH) -Wl,--whole-archive -lpvode -Wl,--no-whole-archive \ - $(LDFLAGS) - @$(CXX) -shared -Wl,-soname,libpvpre.so.1.0.0 -o $(BOUT_LIB_PATH)/libpvpre_.so \ - -L $(BOUT_LIB_PATH) -Wl,--whole-archive -lpvpre -Wl,--no-whole-archive \ - $(LDFLAGS) - @mv $(BOUT_LIB_PATH)/libpvode_.so $(BOUT_LIB_PATH)/libpvode.so.1.0.0 - @mv $(BOUT_LIB_PATH)/libpvpre_.so $(BOUT_LIB_PATH)/libpvpre.so.1.0.0 - @ln -s libbout++.so.$(BOUT_VERSION) $(LIB_SO) - @ln -s libpvode.so.1.0.0 $(BOUT_LIB_PATH)/libpvode.so - @ln -s libpvpre.so.1.0.0 $(BOUT_LIB_PATH)/libpvpre.so - @@SHARED_EXTRA@ - -# From the legacy build script: -# Then set the last two preqrequisites for 'all' -all: lib end_message - -# Only needed for legacy build script -ifneq ("$(TARGET)","libfast") -# This to make sure build time is always printed correctly -.PHONY: bout++-time.cxx -endif - -checksum: - @echo $(CHECKSUM) - -# From the legacy build script -initial_message: - @echo "" - @echo "----- Compiling BOUT++ -----" - @echo "CXX = " $(CXX) - @echo "FLAGS = " $(BOUT_FLAGS) - @echo "CHECKSUM = " $(CHECKSUM) - @echo "INCLUDE = " $(BOUT_INCLUDE) - @rm -f $(BOUT_LIB_PATH)/libbout++.a - -# From the legacy build script -end_message: - @echo "Finished" - @echo "" diff --git a/src/mesh/boundary_factory.cxx b/src/mesh/boundary_factory.cxx index 5f5978f132..00282566a9 100644 --- a/src/mesh/boundary_factory.cxx +++ b/src/mesh/boundary_factory.cxx @@ -1,3 +1,5 @@ +#include "bout/parallel_boundary_op.hxx" +#include "bout/parallel_boundary_region.hxx" #include #include #include @@ -41,10 +43,12 @@ BoundaryFactory::BoundaryFactory() { addMod(new BoundaryFromFieldAligned(), "fromFieldAligned"); // Parallel boundaries - add(new BoundaryOpPar_dirichlet(), "parallel_dirichlet"); - add(new BoundaryOpPar_dirichlet_O3(), "parallel_dirichlet_O3"); - add(new BoundaryOpPar_dirichlet_interp(), "parallel_dirichlet_interp"); - add(new BoundaryOpPar_neumann(), "parallel_neumann"); + add(new BoundaryOpPar_dirichlet_o1(), "parallel_dirichlet_o1"); + add(new BoundaryOpPar_dirichlet_o2(), "parallel_dirichlet_o2"); + add(new BoundaryOpPar_dirichlet_o3(), "parallel_dirichlet_o3"); + add(new BoundaryOpPar_neumann_o1(), "parallel_neumann_o1"); + add(new BoundaryOpPar_neumann_o2(), "parallel_neumann_o2"); + add(new BoundaryOpPar_neumann_o3(), "parallel_neumann_o3"); } BoundaryFactory::~BoundaryFactory() { diff --git a/src/mesh/coordinates.cxx b/src/mesh/coordinates.cxx index 25d623aad8..4e515449ca 100644 --- a/src/mesh/coordinates.cxx +++ b/src/mesh/coordinates.cxx @@ -925,7 +925,7 @@ void Coordinates::outputVars(Options& output_options) { } const Field2D& Coordinates::zlength() const { - BOUT_OMP(critical) + BOUT_OMP_SAFE(critical) if (not zlength_cache) { zlength_cache = std::make_unique(0., localmesh); @@ -1502,7 +1502,7 @@ Field3D Coordinates::DDY(const Field3D& f, CELL_LOC outloc, const std::string& m if (!f.hasParallelSlices() and !transform->canToFromFieldAligned()) { Field3D f_parallel = f; transform->calcParallelSlices(f_parallel); - f_parallel.applyParallelBoundary("parallel_neumann"); + f_parallel.applyParallelBoundary("parallel_neumann_o2"); return bout::derivatives::index::DDY(f_parallel, outloc, method, region); } #endif @@ -1528,7 +1528,7 @@ Field3D Coordinates::DDZ(const Field3D& f, CELL_LOC outloc, const std::string& m // Parallel gradient Coordinates::FieldMetric Coordinates::Grad_par(const Field2D& var, - MAYBE_UNUSED(CELL_LOC outloc), + [[maybe_unused]] CELL_LOC outloc, const std::string& UNUSED(method)) { TRACE("Coordinates::Grad_par( Field2D )"); ASSERT1(location == outloc @@ -1550,7 +1550,7 @@ Field3D Coordinates::Grad_par(const Field3D& var, CELL_LOC outloc, // vparallel times the parallel derivative along unperturbed B-field Coordinates::FieldMetric Coordinates::Vpar_Grad_par(const Field2D& v, const Field2D& f, - MAYBE_UNUSED(CELL_LOC outloc), + [[maybe_unused]] CELL_LOC outloc, const std::string& UNUSED(method)) { ASSERT1(location == outloc || (outloc == CELL_DEFAULT && location == f.getLocation())); @@ -1829,8 +1829,8 @@ Field3D Coordinates::Laplace(const Field3D& f, CELL_LOC outloc, // Full perpendicular Laplacian, in form of inverse of Laplacian operator in LaplaceXY // solver -Field2D Coordinates::Laplace_perpXY(MAYBE_UNUSED(const Field2D& A), - MAYBE_UNUSED(const Field2D& f)) { +Field2D Coordinates::Laplace_perpXY([[maybe_unused]] const Field2D& A, + [[maybe_unused]] const Field2D& f) { TRACE("Coordinates::Laplace_perpXY( Field2D )"); #if not(BOUT_USE_METRIC_3D) Field2D result; @@ -1908,7 +1908,7 @@ Coordinates::Grad2_par2_DDY_invSg(CELL_LOC outloc, const std::string& method) co // Communicate to get parallel slices localmesh->communicate(*invSgCache); - invSgCache->applyParallelBoundary("parallel_neumann"); + invSgCache->applyParallelBoundary("parallel_neumann_o2"); // cache auto ptr = std::make_unique(); diff --git a/src/mesh/data/gridfromfile.cxx b/src/mesh/data/gridfromfile.cxx index 7e875bd109..81faca3dc5 100644 --- a/src/mesh/data/gridfromfile.cxx +++ b/src/mesh/data/gridfromfile.cxx @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include @@ -14,7 +14,7 @@ #include GridFile::GridFile(std::string gridfilename) - : GridDataSource(true), data(bout::OptionsNetCDF(gridfilename).read()), + : GridDataSource(true), data(bout::OptionsIO::create(gridfilename)->read()), filename(std::move(gridfilename)) { TRACE("GridFile constructor"); @@ -134,10 +134,10 @@ bool GridFile::get(Mesh* m, Field3D& var, const std::string& name, BoutReal def, namespace { /// Visitor that returns the shape of its argument struct GetDimensions { - std::vector operator()(MAYBE_UNUSED(bool value)) { return {1}; } - std::vector operator()(MAYBE_UNUSED(int value)) { return {1}; } - std::vector operator()(MAYBE_UNUSED(BoutReal value)) { return {1}; } - std::vector operator()(MAYBE_UNUSED(const std::string& value)) { return {1}; } + std::vector operator()([[maybe_unused]] bool value) { return {1}; } + std::vector operator()([[maybe_unused]] int value) { return {1}; } + std::vector operator()([[maybe_unused]] BoutReal value) { return {1}; } + std::vector operator()([[maybe_unused]] const std::string& value) { return {1}; } std::vector operator()(const Array& array) { return {array.size()}; } std::vector operator()(const Matrix& array) { const auto shape = array.shape(); @@ -157,7 +157,7 @@ template bool GridFile::getField(Mesh* m, T& var, const std::string& name, BoutReal def, CELL_LOC location) { static_assert( - bout::utils::is_Field::value, + bout::utils::is_Field_v, "templated GridFile::getField only works for Field2D, Field3D or FieldPerp"); Timer timer("io"); @@ -172,7 +172,7 @@ bool GridFile::getField(Mesh* m, T& var, const std::string& name, BoutReal def, return false; } - Options option = data[name]; + Options& option = data[name]; // Global (x, y, z) dimensions of field const std::vector size = bout::utils::visit(GetDimensions{}, option.value); @@ -195,7 +195,7 @@ bool GridFile::getField(Mesh* m, T& var, const std::string& name, BoutReal def, } case 3: { // Check size if getting Field3D - if (bout::utils::is_Field2D::value or bout::utils::is_FieldPerp::value) { + if constexpr (bout::utils::is_Field2D_v or bout::utils::is_FieldPerp_v) { output_warn.write( "WARNING: Variable '{:s}' should be 2D, but has {:d} dimensions. Ignored\n", name, size.size()); @@ -272,7 +272,7 @@ bool GridFile::getField(Mesh* m, T& var, const std::string& name, BoutReal def, name, grid_xguards, mxg); } - if (not bout::utils::is_FieldPerp::value) { + if constexpr (not bout::utils::is_FieldPerp_v) { // Check if field dimensions are correct. y-direction if (grid_yguards > 0) { // including ghostpoints @@ -325,7 +325,7 @@ bool GridFile::getField(Mesh* m, T& var, const std::string& name, BoutReal def, } } - if (not bout::utils::is_FieldPerp::value) { + if constexpr (not bout::utils::is_FieldPerp_v) { ///If field does not include ghost points in y-direction -> ///Upper and lower Y boundaries copied from nearest point if (grid_yguards == 0) { @@ -471,10 +471,10 @@ void GridFile::readField(Mesh* m, const std::string& name, int UNUSED(ys), int U } } -bool GridFile::get(MAYBE_UNUSED(Mesh* m), MAYBE_UNUSED(std::vector& var), - MAYBE_UNUSED(const std::string& name), MAYBE_UNUSED(int len), - MAYBE_UNUSED(int offset), - MAYBE_UNUSED(GridDataSource::Direction dir)) { +bool GridFile::get([[maybe_unused]] Mesh* m, [[maybe_unused]] std::vector& var, + [[maybe_unused]] const std::string& name, [[maybe_unused]] int len, + [[maybe_unused]] int offset, + [[maybe_unused]] GridDataSource::Direction dir) { TRACE("GridFile::get(vector)"); return false; @@ -499,8 +499,7 @@ bool GridFile::get(Mesh* UNUSED(m), std::vector& var, const std::strin bool GridFile::hasXBoundaryGuards(Mesh* m) { // Global (x,y) dimensions of some field // a grid file should always contain "dx" - Options option = data["dx"]; - const std::vector size = bout::utils::visit(GetDimensions{}, option.value); + const std::vector size = bout::utils::visit(GetDimensions{}, data["dx"].value); if (size.empty()) { // handle case where "dx" is not present - non-standard grid file @@ -535,8 +534,7 @@ bool GridFile::readgrid_3dvar_fft(Mesh* m, const std::string& name, int yread, i } /// Check the size of the data - Options option = data[name]; - const std::vector size = bout::utils::visit(GetDimensions{}, option.value); + const std::vector size = bout::utils::visit(GetDimensions{}, data[name].value); if (size.size() != 3) { output_warn.write("\tWARNING: Number of dimensions of {:s} incorrect\n", name); @@ -622,7 +620,7 @@ bool GridFile::readgrid_3dvar_real(const std::string& name, int yread, int ydest return false; } - Options option = data[name]; + Options& option = data[name]; /// Check the size of the data const std::vector size = bout::utils::visit(GetDimensions{}, option.value); @@ -665,7 +663,7 @@ bool GridFile::readgrid_perpvar_fft(Mesh* m, const std::string& name, int xread, } /// Check the size of the data - Options option = data[name]; + Options& option = data[name]; const std::vector size = bout::utils::visit(GetDimensions{}, option.value); if (size.size() != 2) { @@ -748,7 +746,7 @@ bool GridFile::readgrid_perpvar_real(const std::string& name, int xread, int xde } /// Check the size of the data - Options option = data[name]; + Options& option = data[name]; const std::vector size = bout::utils::visit(GetDimensions{}, option.value); if (size.size() != 2) { diff --git a/src/mesh/data/makefile b/src/mesh/data/makefile deleted file mode 100644 index 28d8eb22a9..0000000000 --- a/src/mesh/data/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = gridfromoptions.cxx gridfromfile.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/mesh/difops.cxx b/src/mesh/difops.cxx index 9b7665ad30..2e25dfeedb 100644 --- a/src/mesh/difops.cxx +++ b/src/mesh/difops.cxx @@ -645,7 +645,7 @@ Field3D bracket(const Field3D& f, const Field2D& g, BRACKET_METHOD method, } ASSERT1(outloc == g.getLocation()); - MAYBE_UNUSED(Mesh * mesh) = f.getMesh(); + [[maybe_unused]] Mesh* mesh = f.getMesh(); Field3D result{emptyFrom(f).setLocation(outloc)}; @@ -774,7 +774,7 @@ Field3D bracket(const Field3D& f, const Field2D& g, BRACKET_METHOD method, case BRACKET_ARAKAWA_OLD: { #if not(BOUT_USE_METRIC_3D) const int ncz = mesh->LocalNz; - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int jx = mesh->xstart; jx <= mesh->xend; jx++) { for (int jy = mesh->ystart; jy <= mesh->yend; jy++) { const BoutReal partialFactor = 1.0 / (12 * metric->dz(jx, jy)); @@ -862,7 +862,7 @@ Field3D bracket(const Field2D& f, const Field3D& g, BRACKET_METHOD method, } Field3D bracket(const Field3D& f, const Field3D& g, BRACKET_METHOD method, - CELL_LOC outloc, MAYBE_UNUSED(Solver* solver)) { + CELL_LOC outloc, [[maybe_unused]] Solver* solver) { TRACE("Field3D, Field3D"); ASSERT1_FIELDS_COMPATIBLE(f, g); @@ -1100,7 +1100,7 @@ Field3D bracket(const Field3D& f, const Field3D& g, BRACKET_METHOD method, Field3D f_temp = f; Field3D g_temp = g; - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int jx = mesh->xstart; jx <= mesh->xend; jx++) { for (int jy = mesh->ystart; jy <= mesh->yend; jy++) { #if not(BOUT_USE_METRIC_3D) diff --git a/src/mesh/fv_ops.cxx b/src/mesh/fv_ops.cxx index 0a5d5f9624..cd5b924e9e 100644 --- a/src/mesh/fv_ops.cxx +++ b/src/mesh/fv_ops.cxx @@ -22,7 +22,7 @@ Slices makeslices(bool use_slices, const T& field) { namespace FV { -// Div ( a Grad_perp(f) ) -- ∇⊥ ( a ⋅ ∇⊥ f) -- Vorticity +// Div ( a Grad_perp(f) ) -- ∇ ⋅ ( a ∇⊥ f) -- Vorticity Field3D Div_a_Grad_perp(const Field3D& a, const Field3D& f) { ASSERT2(a.getLocation() == f.getLocation()); diff --git a/src/mesh/impls/bout/boutmesh.cxx b/src/mesh/impls/bout/boutmesh.cxx index a802d3f5b3..16061cd47e 100644 --- a/src/mesh/impls/bout/boutmesh.cxx +++ b/src/mesh/impls/bout/boutmesh.cxx @@ -35,6 +35,7 @@ #include "boutmesh.hxx" +#include #include #include #include @@ -44,6 +45,7 @@ #include #include #include +#include #include #include @@ -80,9 +82,6 @@ BoutMesh::~BoutMesh() { for (const auto& bndry : boundary) { delete bndry; } - for (const auto& bndry : par_boundary) { - delete bndry; - } if (comm_x != MPI_COMM_NULL) { MPI_Comm_free(&comm_x); @@ -333,7 +332,9 @@ void BoutMesh::setDerivedGridSizes() { } GlobalNx = nx; - GlobalNy = ny + 2 * MYG; + GlobalNy = + ny + + 2 * MYG; // Note: For double null this should be be 4 * MYG if boundary cells are stored GlobalNz = nz; // If we've got a second pair of diverator legs, we need an extra @@ -374,6 +375,7 @@ void BoutMesh::setDerivedGridSizes() { } // Set global offsets + // Note: These don't properly include guard/boundary cells OffsetX = PE_XIND * MXSUB; OffsetY = PE_YIND * MYSUB; OffsetZ = 0; @@ -392,6 +394,48 @@ void BoutMesh::setDerivedGridSizes() { zstart = MZG; zend = MZG + MZSUB - 1; + + // Mapping local to global indices + if (periodicX) { + // No boundary cells in X + MapGlobalX = PE_XIND * MXSUB; + MapLocalX = MXG; + MapCountX = MXSUB; + } else { + // X boundaries stored for firstX and lastX processors + if (firstX()) { + MapGlobalX = 0; + MapLocalX = 0; + MapCountX = MXG + MXSUB; + } else { + MapGlobalX = MXG + PE_XIND * MXSUB; + MapLocalX = MXG; // Guard cells not included + MapCountX = MXSUB; + } + if (lastX()) { + // Doesn't change the origin, but adds outer X boundary cells + MapCountX += MXG; + } + } + + if (PE_YIND == 0) { + // Include Y boundary cells + MapGlobalY = 0; + MapLocalY = 0; + MapCountY = MYG + MYSUB; + } else { + MapGlobalY = MYG + PE_YIND * MYSUB; + MapLocalY = MYG; + MapCountY = MYSUB; + } + if (PE_YIND == NYPE - 1) { + // Include Y upper boundary region. + MapCountY += MYG; + } + + MapGlobalZ = 0; + MapLocalZ = MZG; // Omit boundary cells + MapCountZ = MZSUB; } int BoutMesh::load() { @@ -2966,11 +3010,36 @@ RangeIterator BoutMesh::iterateBndryUpperY() const { std::vector BoutMesh::getBoundaries() { return boundary; } -std::vector BoutMesh::getBoundariesPar() { return par_boundary; } +std::vector> +BoutMesh::getBoundariesPar(BoundaryParType type) { + return par_boundary[static_cast(type)]; +} -void BoutMesh::addBoundaryPar(BoundaryRegionPar* bndry) { +void BoutMesh::addBoundaryPar(std::shared_ptr bndry, + BoundaryParType type) { output_info << "Adding new parallel boundary: " << bndry->label << endl; - par_boundary.push_back(bndry); + switch (type) { + case BoundaryParType::xin_fwd: + par_boundary[static_cast(BoundaryParType::xin)].push_back(bndry); + par_boundary[static_cast(BoundaryParType::fwd)].push_back(bndry); + break; + case BoundaryParType::xin_bwd: + par_boundary[static_cast(BoundaryParType::xin)].push_back(bndry); + par_boundary[static_cast(BoundaryParType::bwd)].push_back(bndry); + break; + case BoundaryParType::xout_fwd: + par_boundary[static_cast(BoundaryParType::xout)].push_back(bndry); + par_boundary[static_cast(BoundaryParType::fwd)].push_back(bndry); + break; + case BoundaryParType::xout_bwd: + par_boundary[static_cast(BoundaryParType::xout)].push_back(bndry); + par_boundary[static_cast(BoundaryParType::bwd)].push_back(bndry); + break; + default: + throw BoutException("Unexpected type of boundary {}", toString(type)); + } + par_boundary[static_cast(type)].push_back(bndry); + par_boundary[static_cast(BoundaryParType::all)].push_back(bndry); } Field3D BoutMesh::smoothSeparatrix(const Field3D& f) { diff --git a/src/mesh/impls/bout/boutmesh.hxx b/src/mesh/impls/bout/boutmesh.hxx index 20bf1d7d46..cc674d401a 100644 --- a/src/mesh/impls/bout/boutmesh.hxx +++ b/src/mesh/impls/bout/boutmesh.hxx @@ -1,6 +1,6 @@ -#ifndef __BOUTMESH_H__ -#define __BOUTMESH_H__ +#ifndef BOUT_BOUTMESH_H +#define BOUT_BOUTMESH_H #include "mpi.h" @@ -158,8 +158,10 @@ public: // Boundary regions std::vector getBoundaries() override; - std::vector getBoundariesPar() override; - void addBoundaryPar(BoundaryRegionPar* bndry) override; + std::vector> + getBoundariesPar(BoundaryParType type) override; + void addBoundaryPar(std::shared_ptr bndry, + BoundaryParType type) override; std::set getPossibleBoundaries() const override; Field3D smoothSeparatrix(const Field3D& f) override; @@ -393,8 +395,10 @@ protected: void addBoundaryRegions(); private: - std::vector boundary; // Vector of boundary regions - std::vector par_boundary; // Vector of parallel boundary regions + std::vector boundary; // Vector of boundary regions + std::array>, + static_cast(BoundaryParType::SIZE)> + par_boundary; // Vector of parallel boundary regions ////////////////////////////////////////////////// // Communications @@ -485,4 +489,4 @@ CheckMeshResult checkBoutMeshYDecomposition(int num_y_processors, int ny, int ny_inner); } // namespace bout -#endif // __BOUTMESH_H__ +#endif // BOUT_BOUTMESH_H diff --git a/src/mesh/impls/bout/makefile b/src/mesh/impls/bout/makefile deleted file mode 100644 index 2d8ca5ae5c..0000000000 --- a/src/mesh/impls/bout/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = boutmesh.cxx -SOURCEH = boutmesh.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/mesh/impls/makefile b/src/mesh/impls/makefile deleted file mode 100644 index ed641625de..0000000000 --- a/src/mesh/impls/makefile +++ /dev/null @@ -1,7 +0,0 @@ - -BOUT_TOP = ../../.. - -DIRS = bout -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/mesh/index_derivs.cxx b/src/mesh/index_derivs.cxx index 769315ca68..ebecb96700 100644 --- a/src/mesh/index_derivs.cxx +++ b/src/mesh/index_derivs.cxx @@ -59,7 +59,7 @@ STAGGER Mesh::getStagger(const CELL_LOC inloc, const CELL_LOC outloc, } } -STAGGER Mesh::getStagger(const CELL_LOC vloc, MAYBE_UNUSED(const CELL_LOC inloc), +STAGGER Mesh::getStagger(const CELL_LOC vloc, [[maybe_unused]] const CELL_LOC inloc, const CELL_LOC outloc, const CELL_LOC allowedStaggerLoc) const { TRACE("Mesh::getStagger -- four arguments"); ASSERT1(inloc == outloc); @@ -426,10 +426,9 @@ class FFTDerivativeType { AUTO_TRACE(); ASSERT2(meta.derivType == DERIV::Standard) ASSERT2(var.getMesh()->getNguard(direction) >= nGuards); - ASSERT2(direction == DIRECTION::Z); // Only in Z for now - ASSERT2(stagger == STAGGER::None); // Staggering not currently supported - ASSERT2( - bout::utils::is_Field3D::value); // Should never need to call this with Field2D + ASSERT2(direction == DIRECTION::Z); // Only in Z for now + ASSERT2(stagger == STAGGER::None); // Staggering not currently supported + ASSERT2(bout::utils::is_Field3D_v); // Should never need to call this with Field2D auto* theMesh = var.getMesh(); @@ -446,7 +445,7 @@ class FFTDerivativeType { } const int kmax = ncz / 2 - kfilter; // Up to and including this wavenumber index - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { Array cv(ncz / 2 + 1); const BoutReal kwaveFac = TWOPI / ncz; @@ -485,7 +484,6 @@ class FFTDerivativeType { } static constexpr metaData meta{"FFT", 0, DERIV::Standard}; }; -constexpr metaData FFTDerivativeType::meta; class FFT2ndDerivativeType { public: @@ -494,10 +492,9 @@ class FFT2ndDerivativeType { AUTO_TRACE(); ASSERT2(meta.derivType == DERIV::StandardSecond); ASSERT2(var.getMesh()->getNguard(direction) >= nGuards); - ASSERT2(direction == DIRECTION::Z); // Only in Z for now - ASSERT2(stagger == STAGGER::None); // Staggering not currently supported - ASSERT2( - bout::utils::is_Field3D::value); // Should never need to call this with Field2D + ASSERT2(direction == DIRECTION::Z); // Only in Z for now + ASSERT2(stagger == STAGGER::None); // Staggering not currently supported + ASSERT2(bout::utils::is_Field3D_v); // Should never need to call this with Field2D auto* theMesh = var.getMesh(); @@ -505,7 +502,7 @@ class FFT2ndDerivativeType { const int ncz = theMesh->getNpoints(direction); const int kmax = ncz / 2; - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { Array cv(ncz / 2 + 1); const BoutReal kwaveFac = TWOPI / ncz; @@ -544,7 +541,6 @@ class FFT2ndDerivativeType { } static constexpr metaData meta{"FFT", 0, DERIV::StandardSecond}; }; -constexpr metaData FFT2ndDerivativeType::meta; produceCombinations, Set, Set>, @@ -574,7 +570,6 @@ class SplitFluxDerivativeType { } static constexpr metaData meta{"SPLIT", 2, DERIV::Flux}; }; -constexpr metaData SplitFluxDerivativeType::meta; produceCombinations< Set(floor(delta_x(x, y, z))); @@ -88,7 +85,7 @@ void XZBilinear::calcWeights(const Field3D& delta_x, const Field3D& delta_z, void XZBilinear::calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, const std::string& region) { - skip_mask = mask; + setMask(mask); calcWeights(delta_x, delta_z, region); } @@ -96,15 +93,12 @@ Field3D XZBilinear::interpolate(const Field3D& f, const std::string& region) con ASSERT1(f.getMesh() == localmesh); Field3D f_interp{emptyFrom(f)}; - BOUT_FOR(i, f.getRegion(region)) { + const auto curregion{getRegion(region)}; + BOUT_FOR(i, curregion) { const int x = i.x(); const int y = i.y(); const int z = i.z(); - if (skip_mask(x, y, z)) { - continue; - } - const int y_next = y + y_offset; // Due to lack of guard cells in z-direction, we need to ensure z-index // wraps around diff --git a/src/mesh/interpolation/hermite_spline_xz.cxx b/src/mesh/interpolation/hermite_spline_xz.cxx index 029edb61ff..a8e5df7cdf 100644 --- a/src/mesh/interpolation/hermite_spline_xz.cxx +++ b/src/mesh/interpolation/hermite_spline_xz.cxx @@ -56,15 +56,12 @@ void XZHermiteSpline::calcWeights(const Field3D& delta_x, const Field3D& delta_z const std::string& region) { const int ncz = localmesh->LocalNz; - BOUT_FOR(i, delta_x.getRegion(region)) { + const auto curregion{getRegion(region)}; + BOUT_FOR(i, curregion) { const int x = i.x(); const int y = i.y(); const int z = i.z(); - if (skip_mask(x, y, z)) { - continue; - } - // The integer part of xt_prime, zt_prime are the indices of the cell // containing the field line end-point i_corner(x, y, z) = static_cast(floor(delta_x(x, y, z))); @@ -116,7 +113,7 @@ void XZHermiteSpline::calcWeights(const Field3D& delta_x, const Field3D& delta_z void XZHermiteSpline::calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, const std::string& region) { - skip_mask = mask; + setMask(mask); calcWeights(delta_x, delta_z, region); } @@ -179,15 +176,12 @@ Field3D XZHermiteSpline::interpolate(const Field3D& f, const std::string& region localmesh->wait(h); } - BOUT_FOR(i, f.getRegion(region)) { + const auto curregion{getRegion(region)}; + BOUT_FOR(i, curregion) { const int x = i.x(); const int y = i.y(); const int z = i.z(); - if (skip_mask(x, y, z)) { - continue; - } - // Due to lack of guard cells in z-direction, we need to ensure z-index // wraps around const int z_mod = k_corner(x, y, z); diff --git a/src/mesh/interpolation/hermite_spline_z.cxx b/src/mesh/interpolation/hermite_spline_z.cxx index 921094af73..c4c44cb7b4 100644 --- a/src/mesh/interpolation/hermite_spline_z.cxx +++ b/src/mesh/interpolation/hermite_spline_z.cxx @@ -192,10 +192,3 @@ void ZInterpolationFactory::ensureRegistered() {} namespace { RegisterZInterpolation registerzinterphermitespline{"hermitespline"}; } // namespace - -constexpr decltype(ZInterpolationFactory::type_name) ZInterpolationFactory::type_name; -constexpr decltype(ZInterpolationFactory::section_name) - ZInterpolationFactory::section_name; -constexpr decltype(ZInterpolationFactory::option_name) ZInterpolationFactory::option_name; -constexpr decltype(ZInterpolationFactory::default_type) - ZInterpolationFactory::default_type; diff --git a/src/mesh/interpolation/lagrange_4pt_xz.cxx b/src/mesh/interpolation/lagrange_4pt_xz.cxx index e68a7831fa..92c14ecfd5 100644 --- a/src/mesh/interpolation/lagrange_4pt_xz.cxx +++ b/src/mesh/interpolation/lagrange_4pt_xz.cxx @@ -39,16 +39,12 @@ XZLagrange4pt::XZLagrange4pt(int y_offset, Mesh* mesh) void XZLagrange4pt::calcWeights(const Field3D& delta_x, const Field3D& delta_z, const std::string& region) { - - BOUT_FOR(i, delta_x.getRegion(region)) { + const auto curregion{getRegion(region)}; + BOUT_FOR(i, curregion) { const int x = i.x(); const int y = i.y(); const int z = i.z(); - if (skip_mask(x, y, z)) { - continue; - } - // The integer part of xt_prime, zt_prime are the indices of the cell // containing the field line end-point i_corner(x, y, z) = static_cast(floor(delta_x(x, y, z))); @@ -81,7 +77,7 @@ void XZLagrange4pt::calcWeights(const Field3D& delta_x, const Field3D& delta_z, void XZLagrange4pt::calcWeights(const Field3D& delta_x, const Field3D& delta_z, const BoutMask& mask, const std::string& region) { - skip_mask = mask; + setMask(mask); calcWeights(delta_x, delta_z, region); } @@ -90,15 +86,12 @@ Field3D XZLagrange4pt::interpolate(const Field3D& f, const std::string& region) ASSERT1(f.getMesh() == localmesh); Field3D f_interp{emptyFrom(f)}; - BOUT_FOR(i, f.getRegion(region)) { + const auto curregion{getRegion(region)}; + BOUT_FOR(i, curregion) { const int x = i.x(); const int y = i.y(); const int z = i.z(); - if (skip_mask(x, y, z)) { - continue; - } - const int jx = i_corner(x, y, z); const int jx2mnew = (jx == 0) ? 0 : (jx - 1); const int jxpnew = jx + 1; diff --git a/src/mesh/interpolation/makefile b/src/mesh/interpolation/makefile deleted file mode 100644 index e0c3a434eb..0000000000 --- a/src/mesh/interpolation/makefile +++ /dev/null @@ -1,10 +0,0 @@ - -BOUT_TOP = ../../.. - -DIRS = -SOURCEC = bilinear_xz.cxx hermite_spline_xz.cxx \ - monotonic_hermite_spline_xz.cxx lagrange_4pt_xz.cxx \ - hermite_spline_z.cxx interpolation_z.cxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/mesh/interpolation/monotonic_hermite_spline_xz.cxx b/src/mesh/interpolation/monotonic_hermite_spline_xz.cxx index ffbb7b32e3..abedb27733 100644 --- a/src/mesh/interpolation/monotonic_hermite_spline_xz.cxx +++ b/src/mesh/interpolation/monotonic_hermite_spline_xz.cxx @@ -24,7 +24,6 @@ #include "bout/index_derivs_interface.hxx" #include "bout/interpolation_xz.hxx" #include "bout/mesh.hxx" -#include "bout/output.hxx" #include @@ -58,15 +57,12 @@ Field3D XZMonotonicHermiteSpline::interpolate(const Field3D& f, localmesh->wait(h); } - BOUT_FOR(i, f.getRegion(region)) { + const auto curregion{getRegion(region)}; + BOUT_FOR(i, curregion) { const int x = i.x(); const int y = i.y(); const int z = i.z(); - if (skip_mask(x, y, z)) { - continue; - } - // Due to lack of guard cells in z-direction, we need to ensure z-index // wraps around const int ncz = localmesh->LocalNz; diff --git a/src/mesh/interpolation_xz.cxx b/src/mesh/interpolation_xz.cxx index 11dbdc215d..f7f0b457f2 100644 --- a/src/mesh/interpolation_xz.cxx +++ b/src/mesh/interpolation_xz.cxx @@ -93,11 +93,3 @@ RegisterXZInterpolation registerinterpmonotonichermite RegisterXZInterpolation registerinterplagrange4pt{"lagrange4pt"}; RegisterXZInterpolation registerinterpbilinear{"bilinear"}; } // namespace - -constexpr decltype(XZInterpolationFactory::type_name) XZInterpolationFactory::type_name; -constexpr decltype(XZInterpolationFactory::section_name) - XZInterpolationFactory::section_name; -constexpr decltype(XZInterpolationFactory::option_name) - XZInterpolationFactory::option_name; -constexpr decltype(XZInterpolationFactory::default_type) - XZInterpolationFactory::default_type; diff --git a/src/mesh/makefile b/src/mesh/makefile deleted file mode 100644 index c88bc28d8c..0000000000 --- a/src/mesh/makefile +++ /dev/null @@ -1,14 +0,0 @@ - -BOUT_TOP = ../.. - - -DIRS = impls parallel data interpolation -SOURCEC = difops.cxx interpolation_xz.cxx mesh.cxx boundary_standard.cxx \ - boundary_factory.cxx boundary_region.cxx \ - surfaceiter.cxx coordinates.cxx index_derivs.cxx \ - parallel_boundary_region.cxx parallel_boundary_op.cxx fv_ops.cxx \ - coordinates_accessor.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/mesh/mesh.cxx b/src/mesh/mesh.cxx index e754b4fe43..870f3413cd 100644 --- a/src/mesh/mesh.cxx +++ b/src/mesh/mesh.cxx @@ -555,6 +555,14 @@ Mesh::createDefaultCoordinates(const CELL_LOC location, } const Region<>& Mesh::getRegion3D(const std::string& region_name) const { + const auto found = regionMap3D.find(region_name); + if (found == end(regionMap3D)) { + throw BoutException(_("Couldn't find region {:s} in regionMap3D"), region_name); + } + return region3D[found->second]; +} + +size_t Mesh::getRegionID(const std::string& region_name) const { const auto found = regionMap3D.find(region_name); if (found == end(regionMap3D)) { throw BoutException(_("Couldn't find region {:s} in regionMap3D"), region_name); @@ -595,7 +603,21 @@ void Mesh::addRegion3D(const std::string& region_name, const Region<>& region) { throw BoutException(_("Trying to add an already existing region {:s} to regionMap3D"), region_name); } - regionMap3D[region_name] = region; + + std::optional id; + for (size_t i = 0; i < region3D.size(); ++i) { + if (region3D[i] == region) { + id = i; + break; + } + } + if (!id.has_value()) { + id = region3D.size(); + region3D.push_back(region); + } + + regionMap3D[region_name] = id.value(); + output_verbose.write(_("Registered region 3D {:s}"), region_name); output_verbose << "\n:\t" << region.getStats() << "\n"; } @@ -734,7 +756,89 @@ void Mesh::recalculateStaggeredCoordinates() { } } -constexpr decltype(MeshFactory::type_name) MeshFactory::type_name; -constexpr decltype(MeshFactory::section_name) MeshFactory::section_name; -constexpr decltype(MeshFactory::option_name) MeshFactory::option_name; -constexpr decltype(MeshFactory::default_type) MeshFactory::default_type; +std::optional Mesh::getCommonRegion(std::optional lhs, + std::optional rhs) { + if (!lhs.has_value()) { + return rhs; + } + if (!rhs.has_value()) { + return lhs; + } + if (lhs.value() == rhs.value()) { + return lhs; + } + const size_t low = std::min(lhs.value(), rhs.value()); + const size_t high = std::max(lhs.value(), rhs.value()); + + /* This function finds the ID of the region corresponding to the + intersection of two regions, and caches the result. The cache is a + vector, indexed by some function of the two input IDs. Because the + intersection of two regions doesn't depend on the order, and the + intersection of a region with itself is the identity operation, we can + order the IDs numerically and use a generalised triangle number: + $[n (n - 1) / 2] + m$ to construct the cache index. This diagram shows + the result for the first few numbers: + | 0 1 2 3 + ---------------- + 0 | + 1 | 0 + 2 | 1 2 + 3 | 3 4 5 + 4 | 6 7 8 9 + + These indices might be sparse, but presumably we don't expect to store + very many intersections so this shouldn't give much overhead. + + After calculating the cache index, we look it up in the cache (possibly + reallocating to ensure it's large enough). If the index is in the cache, + we can just return it as-is, otherwise we need to do a bit more work. + + First, we need to fully compute the intersection of the two regions. We + then check if this corresponds to an existing region. If so, we cache the + ID of that region and return it. Otherwise, we need to store this new + region in `region3D` -- the index in this vector is the ID we need to + cache and return here. + */ + const size_t pos = (high * (high - 1)) / 2 + low; + if (region3Dintersect.size() <= pos) { + BOUT_OMP_SAFE(critical(mesh_intersection_realloc)) + // By default this function does not need the mutex, however, if we are + // going to allocate global memory, we need to use a mutex. + // Now that we have the mutex, we need to check again whether a + // different thread was faster and already allocated. + // BOUT_OMP_SAFE(single) would work in most cases, but it would fail if the + // function is called in parallel with different arguments. While BOUT++ + // is not currently doing it, other openmp parallised projects might be + // calling BOUT++ in this way. +#if BOUT_USE_OPENMP + if (region3Dintersect.size() <= pos) +#endif + { + region3Dintersect.resize(pos + 1, std::nullopt); + } + } + if (region3Dintersect[pos].has_value()) { + return region3Dintersect[pos]; + } + { + BOUT_OMP_SAFE(critical(mesh_intersection)) + // See comment above why we need to check again in case of OpenMP +#if BOUT_USE_OPENMP + if (!region3Dintersect[pos].has_value()) +#endif + { + auto common = intersection(region3D[low], region3D[high]); + for (size_t i = 0; i < region3D.size(); ++i) { + if (common == region3D[i]) { + region3Dintersect[pos] = i; + break; + } + } + if (!region3Dintersect[pos].has_value()) { + region3Dintersect[pos] = region3D.size(); + region3D.push_back(common); + } + } + } + return region3Dintersect[pos]; +} diff --git a/src/mesh/parallel/fci.cxx b/src/mesh/parallel/fci.cxx index dd7171aaa6..cb8c19bbd7 100644 --- a/src/mesh/parallel/fci.cxx +++ b/src/mesh/parallel/fci.cxx @@ -47,10 +47,11 @@ #include -FCIMap::FCIMap(Mesh& mesh, const Coordinates::FieldMetric& dy, Options& options, - int offset_, BoundaryRegionPar* inner_boundary, - BoundaryRegionPar* outer_boundary, bool zperiodic) - : map_mesh(mesh), offset(offset_), boundary_mask(map_mesh), +FCIMap::FCIMap(Mesh& mesh, const Coordinates::FieldMetric& UNUSED(dy), Options& options, + int offset_, const std::shared_ptr& inner_boundary, + const std::shared_ptr& outer_boundary, bool zperiodic) + : map_mesh(mesh), offset(offset_), + region_no_boundary(map_mesh.getRegion("RGN_NOBNDRY")), corner_boundary_mask(map_mesh) { TRACE("Creating FCIMAP for direction {:d}", offset); @@ -158,6 +159,7 @@ FCIMap::FCIMap(Mesh& mesh, const Coordinates::FieldMetric& dy, Options& options, const int ncz = map_mesh.LocalNz; + BoutMask to_remove(map_mesh); // Serial loop because call to BoundaryRegionPar::addPoint // (probably?) can't be done in parallel BOUT_FOR_SERIAL(i, xt_prime.getRegion("RGN_NOBNDRY")) { @@ -187,7 +189,7 @@ FCIMap::FCIMap(Mesh& mesh, const Coordinates::FieldMetric& dy, Options& options, // indices (forward/backward_xt_prime and forward/backward_zt_prime) // are set to -1 - boundary_mask(x, y, z) = true; + to_remove(x, y, z) = true; // Need to specify the index of the boundary intersection, but // this may not be defined in general. @@ -202,28 +204,14 @@ FCIMap::FCIMap(Mesh& mesh, const Coordinates::FieldMetric& dy, Options& options, // and the gradients dR/dx etc. are evaluated at (x,y,z) // Cache the offsets - const auto i_xp = i.xp(); - const auto i_xm = i.xm(); const auto i_zp = i.zp(); const auto i_zm = i.zm(); - const BoutReal dR_dx = 0.5 * (R[i_xp] - R[i_xm]); - const BoutReal dZ_dx = 0.5 * (Z[i_xp] - Z[i_xm]); + const BoutReal dR_dx = 0.5 * (R[i.xp()] - R[i.xm()]); + const BoutReal dZ_dx = 0.5 * (Z[i.xp()] - Z[i.xm()]); - BoutReal dR_dz, dZ_dz; - // Handle the edge cases in Z - if (z == 0) { - dR_dz = R[i_zp] - R[i]; - dZ_dz = Z[i_zp] - Z[i]; - - } else if (z == map_mesh.LocalNz - 1) { - dR_dz = R[i] - R[i_zm]; - dZ_dz = Z[i] - Z[i_zm]; - - } else { - dR_dz = 0.5 * (R[i_zp] - R[i_zm]); - dZ_dz = 0.5 * (Z[i_zp] - Z[i_zm]); - } + const BoutReal dR_dz = 0.5 * (R[i_zp] - R[i_zm]); + const BoutReal dZ_dz = 0.5 * (Z[i_zp] - Z[i_zm]); const BoutReal det = dR_dx * dZ_dz - dR_dz * dZ_dx; // Determinant of 2x2 matrix @@ -234,17 +222,30 @@ FCIMap::FCIMap(Mesh& mesh, const Coordinates::FieldMetric& dy, Options& options, const BoutReal dx = (dZ_dz * dR - dR_dz * dZ) / det; const BoutReal dz = (dR_dx * dZ - dZ_dx * dR) / det; - // Negative xt_prime means we've hit the inner boundary, otherwise - // the outer boundary - auto* boundary = (xt_prime[i] < 0.0) ? inner_boundary : outer_boundary; + // Negative xt_prime means we've hit the inner boundary, otherwise the + // outer boundary. However, if any of the surrounding points are negative, + // that also means inner. So to differentiate between inner and outer we + // need at least 2 points in the domain. + ASSERT2(map_mesh.xend - map_mesh.xstart >= 2); + auto boundary = (xt_prime[i] < map_mesh.xstart) ? inner_boundary : outer_boundary; boundary->add_point(x, y, z, x + dx, y + 0.5 * offset, - z + dz, // Intersection point in local index space - 0.5 * dy[i], // Distance to intersection - PI // Right-angle intersection + z + dz, // Intersection point in local index space + 0.5, // Distance to intersection + 1 // Default to that there is a point in the other direction ); } + region_no_boundary = region_no_boundary.mask(to_remove); + + interp->setRegion(region_no_boundary); - interp->setMask(boundary_mask); + const auto region = fmt::format("RGN_YPAR_{:+d}", offset); + if (not map_mesh.hasRegion3D(region)) { + // The valid region for this slice + map_mesh.addRegion3D( + region, Region(map_mesh.xstart, map_mesh.xend, map_mesh.ystart + offset, + map_mesh.yend + offset, 0, map_mesh.LocalNz - 1, + map_mesh.LocalNy, map_mesh.LocalNz)); + } } Field3D FCIMap::integrate(Field3D& f) const { @@ -265,48 +266,33 @@ Field3D FCIMap::integrate(Field3D& f) const { result = BoutNaN; #endif - int nz = map_mesh.LocalNz; - - for (int x = map_mesh.xstart; x <= map_mesh.xend; x++) { - for (int y = map_mesh.ystart; y <= map_mesh.yend; y++) { - - int ynext = y + offset; - - for (int z = 0; z < nz; z++) { - if (boundary_mask(x, y, z)) { - continue; - } - - int zm = z - 1; - if (z == 0) { - zm = nz - 1; - } - - BoutReal f_c = centre(x, ynext, z); - - if (corner_boundary_mask(x, y, z) || corner_boundary_mask(x - 1, y, z) - || corner_boundary_mask(x, y, zm) || corner_boundary_mask(x - 1, y, zm) - || (x == map_mesh.xstart)) { - // One of the corners leaves the domain. - // Use the cell centre value, since boundary conditions are not - // currently applied to corners. - result(x, ynext, z) = f_c; - - } else { - BoutReal f_pp = corner(x, ynext, z); // (x+1/2, z+1/2) - BoutReal f_mp = corner(x - 1, ynext, z); // (x-1/2, z+1/2) - BoutReal f_pm = corner(x, ynext, zm); // (x+1/2, z-1/2) - BoutReal f_mm = corner(x - 1, ynext, zm); // (x-1/2, z-1/2) - - // This uses a simple weighted average of centre and corners - // A more sophisticated approach might be to use e.g. Gauss-Lobatto points - // which would include cell edges and corners - result(x, ynext, z) = 0.5 * (f_c + 0.25 * (f_pp + f_mp + f_pm + f_mm)); - - ASSERT2(std::isfinite(result(x, ynext, z))); - } - } + BOUT_FOR(i, region_no_boundary) { + const auto inext = i.yp(offset); + const BoutReal f_c = centre[inext]; + const auto izm = i.zm(); + const int x = i.x(); + const int y = i.y(); + const int z = i.z(); + const int zm = izm.z(); + if (corner_boundary_mask(x, y, z) || corner_boundary_mask(x - 1, y, z) + || corner_boundary_mask(x, y, zm) || corner_boundary_mask(x - 1, y, zm) + || (x == map_mesh.xstart)) { + // One of the corners leaves the domain. + // Use the cell centre value, since boundary conditions are not + // currently applied to corners. + result[inext] = f_c; + } else { + const BoutReal f_pp = corner[inext]; // (x+1/2, z+1/2) + const BoutReal f_mp = corner[inext.xm()]; // (x-1/2, z+1/2) + const BoutReal f_pm = corner[inext.zm()]; // (x+1/2, z-1/2) + const BoutReal f_mm = corner[inext.xm().zm()]; // (x-1/2, z-1/2) + + // This uses a simple weighted average of centre and corners + // A more sophisticated approach might be to use e.g. Gauss-Lobatto points + // which would include cell edges and corners + result[inext] = 0.5 * (f_c + 0.25 * (f_pp + f_mp + f_pm + f_mm)); } + ASSERT2(finite(result[inext])); } return result; } @@ -340,6 +326,7 @@ void FCITransform::calcParallelSlices(Field3D& f) { // Interpolate f onto yup and ydown fields for (const auto& map : field_line_maps) { f.ynext(map.offset) = map.interpolate(f); + f.ynext(map.offset).setRegion(fmt::format("RGN_YPAR_{:+d}", map.offset)); } } diff --git a/src/mesh/parallel/fci.hxx b/src/mesh/parallel/fci.hxx index d03bd688fd..3ec3321a6a 100644 --- a/src/mesh/parallel/fci.hxx +++ b/src/mesh/parallel/fci.hxx @@ -23,8 +23,8 @@ * **************************************************************************/ -#ifndef __FCITRANSFORM_H__ -#define __FCITRANSFORM_H__ +#ifndef BOUT_FCITRANSFORM_H +#define BOUT_FCITRANSFORM_H #include #include @@ -44,8 +44,8 @@ class FCIMap { public: FCIMap() = delete; FCIMap(Mesh& mesh, const Coordinates::FieldMetric& dy, Options& options, int offset, - BoundaryRegionPar* inner_boundary, BoundaryRegionPar* outer_boundary, - bool zperiodic); + const std::shared_ptr& inner_boundary, + const std::shared_ptr& outer_boundary, bool zperiodic); // The mesh this map was created on Mesh& map_mesh; @@ -53,8 +53,9 @@ public: /// Direction of map const int offset; - /// boundary mask - has the field line left the domain - BoutMask boundary_mask; + /// region containing all points where the field line has not left the + /// domain + Region region_no_boundary; /// If any of the integration area has left the domain BoutMask corner_boundary_mask; @@ -78,19 +79,19 @@ public: FCITransform::checkInputGrid(); auto forward_boundary_xin = - new BoundaryRegionPar("FCI_forward", BNDRY_PAR_FWD_XIN, +1, &mesh); - auto backward_boundary_xin = - new BoundaryRegionPar("FCI_backward", BNDRY_PAR_BKWD_XIN, -1, &mesh); + std::make_shared("FCI_forward", BNDRY_PAR_FWD_XIN, +1, &mesh); + auto backward_boundary_xin = std::make_shared( + "FCI_backward", BNDRY_PAR_BKWD_XIN, -1, &mesh); auto forward_boundary_xout = - new BoundaryRegionPar("FCI_forward", BNDRY_PAR_FWD_XOUT, +1, &mesh); - auto backward_boundary_xout = - new BoundaryRegionPar("FCI_backward", BNDRY_PAR_BKWD_XOUT, -1, &mesh); + std::make_shared("FCI_forward", BNDRY_PAR_FWD_XOUT, +1, &mesh); + auto backward_boundary_xout = std::make_shared( + "FCI_backward", BNDRY_PAR_BKWD_XOUT, -1, &mesh); // Add the boundary region to the mesh's vector of parallel boundaries - mesh.addBoundaryPar(forward_boundary_xin); - mesh.addBoundaryPar(backward_boundary_xin); - mesh.addBoundaryPar(forward_boundary_xout); - mesh.addBoundaryPar(backward_boundary_xout); + mesh.addBoundaryPar(forward_boundary_xin, BoundaryParType::xin_fwd); + mesh.addBoundaryPar(backward_boundary_xin, BoundaryParType::xin_bwd); + mesh.addBoundaryPar(forward_boundary_xout, BoundaryParType::xout_fwd); + mesh.addBoundaryPar(backward_boundary_xout, BoundaryParType::xout_bwd); field_line_maps.reserve(mesh.ystart * 2); for (int offset = 1; offset < mesh.ystart + 1; ++offset) { @@ -99,6 +100,22 @@ public: field_line_maps.emplace_back(mesh, dy, options, -offset, backward_boundary_xin, backward_boundary_xout, zperiodic); } + ASSERT0(mesh.ystart == 1); + std::shared_ptr bndries[]{ + forward_boundary_xin, forward_boundary_xout, backward_boundary_xin, + backward_boundary_xout}; + for (auto& bndry : bndries) { + for (const auto& bndry2 : bndries) { + if (bndry->dir == bndry2->dir) { + continue; + } + for (bndry->first(); !bndry->isDone(); bndry->next()) { + if (bndry2->contains(*bndry)) { + bndry->setValid(0); + } + } + } + } } void calcParallelSlices(Field3D& f) override; @@ -126,7 +143,7 @@ public: bool canToFromFieldAligned() const override { return false; } bool requiresTwistShift(bool UNUSED(twist_shift_enabled), - MAYBE_UNUSED(YDirectionType ytype)) override { + [[maybe_unused]] YDirectionType ytype) override { // No Field3Ds require twist-shift, because they cannot be field-aligned ASSERT1(ytype == YDirectionType::Standard); @@ -141,4 +158,4 @@ private: std::vector field_line_maps; }; -#endif // __FCITRANSFORM_H__ +#endif // BOUT_FCITRANSFORM_H diff --git a/src/mesh/parallel/makefile b/src/mesh/parallel/makefile deleted file mode 100644 index 9bbfd1a910..0000000000 --- a/src/mesh/parallel/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../.. - -DIRS = -SOURCEC = shiftedmetric.cxx shiftedmetricinterp.cxx fci.cxx identity.cxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/mesh/parallel/shiftedmetric.cxx b/src/mesh/parallel/shiftedmetric.cxx index c223b1abbc..382052047d 100644 --- a/src/mesh/parallel/shiftedmetric.cxx +++ b/src/mesh/parallel/shiftedmetric.cxx @@ -6,7 +6,9 @@ * */ +#include "bout/parallel_boundary_region.hxx" #include "bout/paralleltransform.hxx" +#include #include #include #include @@ -264,11 +266,8 @@ ShiftedMetric::shiftZ(const Field3D& f, std::vector results{}; - for (auto& phase : phases) { - // In C++17 std::vector::emplace_back returns a reference, which - // would be very useful here! - results.emplace_back(&mesh); - auto& current_result = results.back(); + for (const auto& phase : phases) { + auto& current_result = results.emplace_back(&mesh); current_result.allocate(); current_result.setLocation(f.getLocation()); diff --git a/src/mesh/parallel/shiftedmetricinterp.cxx b/src/mesh/parallel/shiftedmetricinterp.cxx index 214f7ded76..7f3637e79c 100644 --- a/src/mesh/parallel/shiftedmetricinterp.cxx +++ b/src/mesh/parallel/shiftedmetricinterp.cxx @@ -29,7 +29,7 @@ #include "shiftedmetricinterp.hxx" #include "bout/constants.hxx" -#include "bout/mask.hxx" +#include "bout/parallel_boundary_region.hxx" ShiftedMetricInterp::ShiftedMetricInterp(Mesh& mesh, CELL_LOC location_in, Field2D zShift_in, BoutReal zlength_in, @@ -114,11 +114,16 @@ ShiftedMetricInterp::ShiftedMetricInterp(Mesh& mesh, CELL_LOC location_in, interp_from_aligned->calcWeights(zt_prime_from); + int yvalid = mesh.LocalNy - 2 * mesh.ystart; + // avoid overflow - no stencil need more than 5 points + if (yvalid > 20) { + yvalid = 20; + } // Create regions for parallel boundary conditions Field2D dy; mesh.get(dy, "dy", 1.); - auto forward_boundary_xin = - new BoundaryRegionPar("parallel_forward_xin", BNDRY_PAR_FWD_XIN, +1, &mesh); + auto forward_boundary_xin = std::make_shared( + "parallel_forward_xin", BNDRY_PAR_FWD_XIN, +1, &mesh); for (auto it = mesh.iterateBndryUpperY(); not it.isDone(); it.next()) { for (int z = mesh.zstart; z <= mesh.zend; z++) { forward_boundary_xin->add_point( @@ -128,14 +133,13 @@ ShiftedMetricInterp::ShiftedMetricInterp(Mesh& mesh, CELL_LOC location_in, zlength * BoutReal(z) / BoutReal(mesh.GlobalNz) // z + 0.5 * (zShift(it.ind, mesh.yend + 1) - zShift(it.ind, mesh.yend)), 0.25 - * (dy(it.ind, mesh.yend) // dy/2 - + dy(it.ind, mesh.yend + 1)), - 0. // angle? - ); + * (1 // dy/2 + + dy(it.ind, mesh.yend + 1) / dy(it.ind, mesh.yend)), // length + yvalid); } } - auto backward_boundary_xin = - new BoundaryRegionPar("parallel_backward_xin", BNDRY_PAR_BKWD_XIN, -1, &mesh); + auto backward_boundary_xin = std::make_shared( + "parallel_backward_xin", BNDRY_PAR_BKWD_XIN, -1, &mesh); for (auto it = mesh.iterateBndryLowerY(); not it.isDone(); it.next()) { for (int z = mesh.zstart; z <= mesh.zend; z++) { backward_boundary_xin->add_point( @@ -145,15 +149,14 @@ ShiftedMetricInterp::ShiftedMetricInterp(Mesh& mesh, CELL_LOC location_in, zlength * BoutReal(z) / BoutReal(mesh.GlobalNz) // z + 0.5 * (zShift(it.ind, mesh.ystart) - zShift(it.ind, mesh.ystart - 1)), 0.25 - * (dy(it.ind, mesh.ystart - 1) // dy/2 - + dy(it.ind, mesh.ystart)), - 0. // angle? - ); + * (1 // dy/2 + + dy(it.ind, mesh.ystart - 1) / dy(it.ind, mesh.ystart)), + yvalid); } } // Create regions for parallel boundary conditions - auto forward_boundary_xout = - new BoundaryRegionPar("parallel_forward_xout", BNDRY_PAR_FWD_XOUT, +1, &mesh); + auto forward_boundary_xout = std::make_shared( + "parallel_forward_xout", BNDRY_PAR_FWD_XOUT, +1, &mesh); for (auto it = mesh.iterateBndryUpperY(); not it.isDone(); it.next()) { for (int z = mesh.zstart; z <= mesh.zend; z++) { forward_boundary_xout->add_point( @@ -163,14 +166,13 @@ ShiftedMetricInterp::ShiftedMetricInterp(Mesh& mesh, CELL_LOC location_in, zlength * BoutReal(z) / BoutReal(mesh.GlobalNz) // z + 0.5 * (zShift(it.ind, mesh.yend + 1) - zShift(it.ind, mesh.yend)), 0.25 - * (dy(it.ind, mesh.yend) // dy/2 - + dy(it.ind, mesh.yend + 1)), - 0. // angle? - ); + * (1 // dy/2 + + dy(it.ind, mesh.yend + 1) / dy(it.ind, mesh.yend)), + yvalid); } } - auto backward_boundary_xout = - new BoundaryRegionPar("parallel_backward_xout", BNDRY_PAR_BKWD_XOUT, -1, &mesh); + auto backward_boundary_xout = std::make_shared( + "parallel_backward_xout", BNDRY_PAR_BKWD_XOUT, -1, &mesh); for (auto it = mesh.iterateBndryLowerY(); not it.isDone(); it.next()) { for (int z = mesh.zstart; z <= mesh.zend; z++) { backward_boundary_xout->add_point( @@ -180,18 +182,17 @@ ShiftedMetricInterp::ShiftedMetricInterp(Mesh& mesh, CELL_LOC location_in, zlength * BoutReal(z) / BoutReal(mesh.GlobalNz) // z + 0.5 * (zShift(it.ind, mesh.ystart) - zShift(it.ind, mesh.ystart - 1)), 0.25 - * (dy(it.ind, mesh.ystart - 1) // dy/2 - + dy(it.ind, mesh.ystart)), - 0. // angle? - ); + * (dy(it.ind, mesh.ystart - 1) / dy(it.ind, mesh.ystart) // dy/2 + + 1), + yvalid); } } // Add the boundary region to the mesh's vector of parallel boundaries - mesh.addBoundaryPar(forward_boundary_xin); - mesh.addBoundaryPar(backward_boundary_xin); - mesh.addBoundaryPar(forward_boundary_xout); - mesh.addBoundaryPar(backward_boundary_xout); + mesh.addBoundaryPar(forward_boundary_xin, BoundaryParType::xin_fwd); + mesh.addBoundaryPar(backward_boundary_xin, BoundaryParType::xin_bwd); + mesh.addBoundaryPar(forward_boundary_xout, BoundaryParType::xout_fwd); + mesh.addBoundaryPar(backward_boundary_xout, BoundaryParType::xin_bwd); } void ShiftedMetricInterp::checkInputGrid() { diff --git a/src/mesh/parallel/shiftedmetricinterp.hxx b/src/mesh/parallel/shiftedmetricinterp.hxx index 86ecfac853..6852ea15a9 100644 --- a/src/mesh/parallel/shiftedmetricinterp.hxx +++ b/src/mesh/parallel/shiftedmetricinterp.hxx @@ -24,11 +24,12 @@ * **************************************************************************/ -#ifndef __SHIFTEDINTERP_H__ -#define __SHIFTEDINTERP_H__ +#ifndef BOUT_SHIFTEDINTERP_H +#define BOUT_SHIFTEDINTERP_H #include #include +#include /*! * Shifted metric method @@ -78,14 +79,17 @@ public: bool canToFromFieldAligned() const override { return true; } std::vector - getWeightsForYUpApproximation(int i, int j, int k) override { - return parallel_slice_interpolators[yup_index]->getWeightsForYApproximation(i, j, k, - 1); - } - std::vector - getWeightsForYDownApproximation(int i, int j, int k) override { - return parallel_slice_interpolators[ydown_index]->getWeightsForYApproximation(i, j, k, - -1); + getWeightsForYApproximation(int i, int j, int k, int y_offset) override { +#if CHECK > 0 + if (y_offset == 0) { + throw BoutException("Cannot get ShiftedMetricInterp parallel slice at zero offset"); + } +#endif + const auto index = static_cast(std::abs(y_offset) - 1) + + ((y_offset > 0) ? yup_index : ydown_index); + + return parallel_slice_interpolators[index]->getWeightsForYApproximation(i, j, k, + y_offset); } bool requiresTwistShift(bool twist_shift_enabled, YDirectionType ytype) override { @@ -125,4 +129,4 @@ private: const std::size_t ydown_index; }; -#endif // __SHIFTEDINTERP_H__ +#endif // BOUT_SHIFTEDINTERP_H diff --git a/src/mesh/parallel_boundary_op.cxx b/src/mesh/parallel_boundary_op.cxx index a1b2812581..ebd9852791 100644 --- a/src/mesh/parallel_boundary_op.cxx +++ b/src/mesh/parallel_boundary_op.cxx @@ -5,43 +5,16 @@ #include "bout/mesh.hxx" #include "bout/output.hxx" -using bout::generator::Context; - -BoutReal BoundaryOpPar::getValue(int x, int y, int z, BoutReal t) { - - Mesh* mesh = bndry->localmesh; - - BoutReal value; - - switch (value_type) { - case ValueType::GEN: - // This works but doesn't quite do the right thing... should - // generate value on the boundary, but that gives wrong - // answer. This instead generates the value at the gridpoint - return gen_values->generate(Context(x, y, z, CELL_CENTRE, mesh, t)); - case ValueType::FIELD: - value = (*field_values)(x, y, z); - return value; - case ValueType::REAL: - return real_value; - default: - throw BoutException("Invalid value_type encountered in BoundaryOpPar::getValue"); - } -} - BoutReal BoundaryOpPar::getValue(const BoundaryRegionPar& bndry, BoutReal t) { - - Mesh* mesh = bndry.localmesh; - BoutReal value; switch (value_type) { case ValueType::GEN: - return gen_values->generate( - Context(bndry.s_x, bndry.s_y, bndry.s_z, CELL_CENTRE, mesh, t)); + return gen_values->generate(bout::generator::Context( + bndry.s_x(), bndry.s_y(), bndry.s_z(), CELL_CENTRE, bndry.localmesh, t)); case ValueType::FIELD: // FIXME: Interpolate to s_x, s_y, s_z... - value = (*field_values)(bndry.x, bndry.y, bndry.z); + value = (*field_values)[bndry.ind()]; return value; case ValueType::REAL: return real_value; @@ -49,204 +22,3 @@ BoutReal BoundaryOpPar::getValue(const BoundaryRegionPar& bndry, BoutReal t) { throw BoutException("Invalid value_type encountered in BoundaryOpPar::getValue"); } } - -////////////////////////////////////////// -// Dirichlet boundary - -BoundaryOpPar* BoundaryOpPar_dirichlet::clone(BoundaryRegionPar* region, - const std::list& args) { - if (!args.empty()) { - try { - real_value = stringToReal(args.front()); - return new BoundaryOpPar_dirichlet(region, real_value); - } catch (const BoutException&) { - std::shared_ptr newgen = nullptr; - // First argument should be an expression - newgen = FieldFactory::get()->parse(args.front()); - return new BoundaryOpPar_dirichlet(region, newgen); - } - } - return new BoundaryOpPar_dirichlet(region); -} - -BoundaryOpPar* BoundaryOpPar_dirichlet::clone(BoundaryRegionPar* region, Field3D* f) { - return new BoundaryOpPar_dirichlet(region, f); -} - -void BoundaryOpPar_dirichlet::apply(Field3D& f, BoutReal t) { - Field3D& f_next = f.ynext(bndry->dir); - - Coordinates& coord = *(f.getCoordinates()); - - // Loop over grid points If point is in boundary, then fill in - // f_next such that the field would be VALUE on the boundary - for (bndry->first(); !bndry->isDone(); bndry->next()) { - // temp variables for convenience - int x = bndry->x; - int y = bndry->y; - int z = bndry->z; - - // Generate the boundary value - BoutReal value = getValue(*bndry, t); - - // Scale the field and normalise to the desired value - BoutReal y_prime = bndry->length; - BoutReal f2 = (f(x, y, z) - value) * (coord.dy(x, y, z) - y_prime) / y_prime; - - f_next(x, y + bndry->dir, z) = value - f2; - } -} - -////////////////////////////////////////// -// Dirichlet boundary - Third order - -BoundaryOpPar* BoundaryOpPar_dirichlet_O3::clone(BoundaryRegionPar* region, - const std::list& args) { - if (!args.empty()) { - try { - real_value = stringToReal(args.front()); - return new BoundaryOpPar_dirichlet_O3(region, real_value); - } catch (const BoutException&) { - std::shared_ptr newgen = nullptr; - // First argument should be an expression - newgen = FieldFactory::get()->parse(args.front()); - return new BoundaryOpPar_dirichlet_O3(region, newgen); - } - } - return new BoundaryOpPar_dirichlet_O3(region); -} - -BoundaryOpPar* BoundaryOpPar_dirichlet_O3::clone(BoundaryRegionPar* region, Field3D* f) { - return new BoundaryOpPar_dirichlet_O3(region, f); -} - -void BoundaryOpPar_dirichlet_O3::apply(Field3D& f, BoutReal t) { - - Field3D& f_next = f.ynext(bndry->dir); - Field3D& f_prev = f.ynext(-bndry->dir); - - Coordinates& coord = *(f.getCoordinates()); - - // Loop over grid points If point is in boundary, then fill in - // f_next such that the field would be VALUE on the boundary - for (bndry->first(); !bndry->isDone(); bndry->next()) { - // temp variables for convenience - int x = bndry->x; - int y = bndry->y; - int z = bndry->z; - - // Generate the boundary value - BoutReal fb = getValue(*bndry, t); - BoutReal f1 = f_prev(x, y - bndry->dir, z); - BoutReal f2 = f(x, y, z); - BoutReal l1 = coord.dy(x, y, z); - BoutReal l2 = bndry->length; - BoutReal l3 = coord.dy(x, y, z) - l2; - - BoutReal denom = (l1 * l1 * l2 + l1 * l2 * l2); - BoutReal term1 = (l2 * l2 * l3 + l2 * l3 * l3); - BoutReal term2 = l1 * (l1 + l2 + l3) * (l2 + l3); - BoutReal term3 = l3 * ((l1 + l2) * l3 + (l1 + l2) * (l1 + l2)); - - f_next(x, y + bndry->dir, z) = (term1 * f1 + term2 * fb - term3 * f2) / denom; - } -} - -////////////////////////////////////////// -// Dirichlet with interpolation - -BoundaryOpPar* BoundaryOpPar_dirichlet_interp::clone(BoundaryRegionPar* region, - const std::list& args) { - if (!args.empty()) { - try { - real_value = stringToReal(args.front()); - return new BoundaryOpPar_dirichlet_interp(region, real_value); - } catch (const BoutException&) { - std::shared_ptr newgen = nullptr; - // First argument should be an expression - newgen = FieldFactory::get()->parse(args.front()); - return new BoundaryOpPar_dirichlet_interp(region, newgen); - } - } - return new BoundaryOpPar_dirichlet_interp(region); -} - -BoundaryOpPar* BoundaryOpPar_dirichlet_interp::clone(BoundaryRegionPar* region, - Field3D* f) { - return new BoundaryOpPar_dirichlet_interp(region, f); -} - -void BoundaryOpPar_dirichlet_interp::apply(Field3D& f, BoutReal t) { - - Field3D& f_next = f.ynext(bndry->dir); - Field3D& f_prev = f.ynext(-bndry->dir); - - Coordinates& coord = *(f.getCoordinates()); - - // Loop over grid points If point is in boundary, then fill in - // f_next such that the field would be VALUE on the boundary - for (bndry->first(); !bndry->isDone(); bndry->next()) { - // temp variables for convenience - int x = bndry->x; - int y = bndry->y; - int z = bndry->z; - - // Generate the boundary value - BoutReal fs = getValue(*bndry, t); - - // Scale the field and normalise to the desired value - BoutReal dy = coord.dy(x, y, z); - BoutReal s = bndry->length * dy; - - f_next(x, y + bndry->dir, z) = - f_prev(x, y - bndry->dir, z) * (1. - (2. * s / (dy + s))) - + 2. * f(x, y, z) * ((s - dy) / s) + fs * (dy / s - (2. / s + 1.)); - } -} - -////////////////////////////////////////// -// Neumann boundary - -BoundaryOpPar* BoundaryOpPar_neumann::clone(BoundaryRegionPar* region, - const std::list& args) { - if (!args.empty()) { - try { - real_value = stringToReal(args.front()); - return new BoundaryOpPar_neumann(region, real_value); - } catch (const BoutException&) { - std::shared_ptr newgen = nullptr; - // First argument should be an expression - newgen = FieldFactory::get()->parse(args.front()); - return new BoundaryOpPar_neumann(region, newgen); - } - } - return new BoundaryOpPar_neumann(region); -} - -BoundaryOpPar* BoundaryOpPar_neumann::clone(BoundaryRegionPar* region, Field3D* f) { - return new BoundaryOpPar_neumann(region, f); -} - -void BoundaryOpPar_neumann::apply(Field3D& f, BoutReal t) { - TRACE("BoundaryOpPar_neumann::apply"); - - Field3D& f_next = f.ynext(bndry->dir); - f_next.allocate(); // Ensure unique before modifying - - Coordinates& coord = *(f.getCoordinates()); - - // If point is in boundary, then fill in f_next such that the derivative - // would be VALUE on the boundary - for (bndry->first(); !bndry->isDone(); bndry->next()) { - // temp variables for convience - int x = bndry->x; - int y = bndry->y; - int z = bndry->z; - - // Generate the boundary value - BoutReal value = getValue(x, y, z, t); - BoutReal dy = coord.dy(x, y, z); - - f_next(x, y + bndry->dir, z) = f(x, y, z) + bndry->dir * value * dy; - } -} diff --git a/src/mesh/parallel_boundary_region.cxx b/src/mesh/parallel_boundary_region.cxx index 3f77d96737..e69de29bb2 100644 --- a/src/mesh/parallel_boundary_region.cxx +++ b/src/mesh/parallel_boundary_region.cxx @@ -1,37 +0,0 @@ -#include "bout/parallel_boundary_region.hxx" - -void BoundaryRegionPar::add_point(const int jx, const int jy, const int jz, - const BoutReal x, const BoutReal y, const BoutReal z, - const BoutReal length, const BoutReal angle) { - bndry_points.push_back({{jx, jy, jz}, {x, y, z}, length, angle}); -} - -void BoundaryRegionPar::first() { - bndry_position = begin(bndry_points); - if (!isDone()) { - x = bndry_position->index.jx; - y = bndry_position->index.jy; - z = bndry_position->index.jz; - s_x = bndry_position->intersection.s_x; - s_y = bndry_position->intersection.s_y; - s_z = bndry_position->intersection.s_z; - length = bndry_position->length; - angle = bndry_position->angle; - } -} - -void BoundaryRegionPar::next() { - ++bndry_position; - if (!isDone()) { - x = bndry_position->index.jx; - y = bndry_position->index.jy; - z = bndry_position->index.jz; - s_x = bndry_position->intersection.s_x; - s_y = bndry_position->intersection.s_y; - s_z = bndry_position->intersection.s_z; - length = bndry_position->length; - angle = bndry_position->angle; - } -} - -bool BoundaryRegionPar::isDone() { return (bndry_position == end(bndry_points)); } diff --git a/src/mesh/parallel_boundary_stencil.cxx.py b/src/mesh/parallel_boundary_stencil.cxx.py new file mode 100644 index 0000000000..d0988ee099 --- /dev/null +++ b/src/mesh/parallel_boundary_stencil.cxx.py @@ -0,0 +1,62 @@ +import os +from tempfile import NamedTemporaryFile as tmpf +from stencils_sympy import dirichlet, neumann, simp, Symbol, Matrix, ccode + + +def gen_code(order, matrix_type): + x = [Symbol("spacing%d" % i) for i in range(order)] + matrix = matrix_type(x) + A = Matrix(order, order, matrix) + + try: + iA = A.inv() + except: + import sys + + print(A, matrix, file=sys.stderr) + raise + return ccode(simp(sum([iA[0, i] * Symbol("value%d" % i) for i in range(order)]))) + + +def run(cmd): + print(cmd) + out = os.system(cmd) + assert out == 0 + + +if __name__ == "__main__": + with tmpf("w", dir=".", delete=False) as f: + f.write("namespace {\n") + f.write( + """ +inline BoutReal pow(BoutReal val, int exp) { + //constexpr int expval = exp; + //static_assert(expval == 2 or expval == 3, "This pow is only for exponent 2 or 3"); + if (exp == 2) { + return val * val; + } + ASSERT3(exp == 3); + return val * val * val; +} +""" + ) + + for order in range(1, 4): + for matrix in dirichlet, neumann: + if order == 1 and matrix == neumann: + continue + print(f"generating {matrix.name}_o{order}") + args = ", ".join( + [ + "BoutReal spacing%d, BoutReal value%d" % (i, i) + for i in range(order) + ] + ) + f.write( + f"inline BoutReal stencil_{matrix.name}_o{order}({args}) {{\n return " + ) + f.write(gen_code(order, matrix)) + f.write(";\n}\n") + f.write("}\n") + run("clang-format -i " + f.name) + run(f"mv {f.name} {__file__[:-3]}") diff --git a/src/mesh/stencils.md b/src/mesh/stencils.md new file mode 100644 index 0000000000..0c7d181481 --- /dev/null +++ b/src/mesh/stencils.md @@ -0,0 +1,29 @@ +Notes concerning the generation of stencils +================ + +We want to create a Taylor function +$f(x-x_0)=\sum_i=0^n \frac{1}{i!}f_i(x-x_0)^i$ where $n$ +is the order of the function, $x_0$ is the point in the boundary +where we want to calculate the function. $f_i$ are some coefficients +that we need to determine. To be precise, only $f_0$ needs to be +determined. +We know that the function has at some points certain values. If the +value at some distance `spacing.f0` is a given value `val` then we +can build a linear system of equations using the above formula. +If rather the derivative is given, the above equations needs to be +differentiated once. + +stencils_sympy.py calculates the coefficients of the above matrix +which represents our system of equations. The derivative is simply +one the factor of the next smaller term (or zero if the there is no +smaller one). This is what is calculated by `taylor`, `dirichlet` +and `neumann`, the respective matrix coefficients. + +sympy does all the heavy lifting on analytically inverting the +matrix. + +With the analytic inversion we can put in the numerical offsets +`spacing.f?` in C++ and get a fast expression for the respective +coefficients. As mentioned before, we do not need the full inverse, +just the first row, as we only care about the value, not about it's +derivative. diff --git a/src/mesh/stencils_sympy.py b/src/mesh/stencils_sympy.py new file mode 100644 index 0000000000..64677f1985 --- /dev/null +++ b/src/mesh/stencils_sympy.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 + +from sympy import Symbol, Eq +from sympy.matrices import Matrix +from sympy.printing import ccode +from sympy.simplify import combsimp as simp +from sympy.utilities.codegen import codegen + + +def pow(a, b): + if b == 0: + return "1" + if b == 1: + return a + else: + return "%s**%d" % (a, b) + + +def factorial(a): + if a == 0 or a == 1: + return 1 + else: + assert a > 0 + return a * factorial(a - 1) + + +def gen_code(order, matrix_type): + x = [Symbol("spacing.f%d" % i) for i in range(order)] + matrix = matrix_type(x) + A = Matrix(order, order, matrix) + + try: + iA = A.inv() + except: + import sys + + print(A, matrix, file=sys.stderr) + raise + ret = "" + for i in range(order): + ret += ccode(simp(iA[0, i]), assign_to="facs.f%d" % i) + ret += "\n" + return ret + + +def taylor(x, i, j): + if j >= 0: + return x[i] ** j / factorial(j) + else: + return 0 + + +class dirichlet: + name = "dirichlet" + + def __init__(self, x): + self.x = x + + def __call__(self, i, j): + return taylor(self.x, i, j) + + +class neumann: + name = "neumann" + + def __init__(self, x): + self.x = x + + def __call__(self, i, j): + if i == 0: + return taylor(self.x, i, j - 1) + else: + return taylor(self.x, i, j) + + +if __name__ == "__main__": + print(gen_code(3, dirichlet)) diff --git a/src/physics/makefile b/src/physics/makefile deleted file mode 100644 index 388cda9c8f..0000000000 --- a/src/physics/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../.. - -SOURCEC = physicsmodel.cxx smoothing.cxx sourcex.cxx gyro_average.cxx snb.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/physics/physicsmodel.cxx b/src/physics/physicsmodel.cxx index cac4bda5cc..9f538895ed 100644 --- a/src/physics/physicsmodel.cxx +++ b/src/physics/physicsmodel.cxx @@ -58,35 +58,25 @@ void DataFileFacade::add(Vector3D* value, const std::string& name, bool save_rep add(value->y, name_prefix + "y"s, save_repeat); add(value->z, name_prefix + "z"s, save_repeat); } - -bool DataFileFacade::write() { - for (const auto& item : data) { - bout::utils::visit(bout::OptionsConversionVisitor{Options::root(), item.name}, - item.value); - if (item.repeat) { - Options::root()[item.name].attributes["time_dimension"] = "t"; - } - } - writeDefaultOutputFile(); - return true; -} } // namespace bout PhysicsModel::PhysicsModel() - : mesh(bout::globals::mesh), - output_file(bout::getOutputFilename(Options::root()), - Options::root()["append"] - .doc("Add output data to existing (dump) files?") - .withDefault(false) - ? bout::OptionsNetCDF::FileMode::append - : bout::OptionsNetCDF::FileMode::replace), - output_enabled(Options::root()["output"]["enabled"] - .doc("Write output files") - .withDefault(true)), - restart_file(bout::getRestartFilename(Options::root())), + : mesh(bout::globals::mesh), output_enabled(Options::root()["output"]["enabled"] + .doc("Write output files") + .withDefault(true)), restart_enabled(Options::root()["restart_files"]["enabled"] .doc("Write restart files") - .withDefault(true)) {} + .withDefault(true)) + +{ + if (output_enabled) { + output_file = bout::OptionsIOFactory::getInstance().createOutput(); + } + + if (restart_enabled) { + restart_file = bout::OptionsIOFactory::getInstance().createRestart(); + } +} void PhysicsModel::initialise(Solver* s) { if (initialised) { @@ -104,7 +94,7 @@ void PhysicsModel::initialise(Solver* s) { const bool restarting = Options::root()["restart"].withDefault(false); if (restarting) { - restart_options = restart_file.read(); + restart_options = restart_file->read(); } // Call user init code to specify evolving variables @@ -187,7 +177,7 @@ int PhysicsModel::postInit(bool restarting) { restart_options["BOUT_VERSION"].force(bout::version::as_double, "PhysicsModel"); // Write _everything_ to restart file - restart_file.write(restart_options); + restart_file->write(restart_options); } // Add monitor to the solver which calls restart.write() and @@ -219,7 +209,7 @@ void PhysicsModel::restartVars(Options& options) { void PhysicsModel::writeRestartFile() { if (restart_enabled) { - restart_file.write(restart_options); + restart_file->write(restart_options); } } @@ -227,20 +217,20 @@ void PhysicsModel::writeOutputFile() { writeOutputFile(output_options); } void PhysicsModel::writeOutputFile(const Options& options) { if (output_enabled) { - output_file.write(options, "t"); + output_file->write(options, "t"); } } void PhysicsModel::writeOutputFile(const Options& options, const std::string& time_dimension) { if (output_enabled) { - output_file.write(options, time_dimension); + output_file->write(options, time_dimension); } } void PhysicsModel::finishOutputTimestep() const { if (output_enabled) { - output_file.verifyTimesteps(); + output_file->verifyTimesteps(); } } diff --git a/src/solver/impls/adams_bashforth/adams_bashforth.cxx b/src/solver/impls/adams_bashforth/adams_bashforth.cxx index bfdea5e126..79161fcdbf 100644 --- a/src/solver/impls/adams_bashforth/adams_bashforth.cxx +++ b/src/solver/impls/adams_bashforth/adams_bashforth.cxx @@ -201,7 +201,7 @@ void AB_integrate_update(Array& update, BoutReal timestep, for (std::size_t j = 0; j < static_cast(order); ++j) { const BoutReal factor = AB_coefficients[j]; - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (std::size_t i = 0; i < static_cast(update.size()); ++i) { update[i] += history[j][i] * factor; } @@ -576,7 +576,7 @@ BoutReal AdamsBashforthSolver::take_step(const BoutReal timeIn, const BoutReal d // std::transform(std::begin(current), std::end(current), std::begin(full_update), // std::begin(result), std::plus{}); if (not(adaptive and followHighOrder)) { - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { result[i] = current[i] + full_update[i]; } @@ -614,7 +614,7 @@ BoutReal AdamsBashforthSolver::take_step(const BoutReal timeIn, const BoutReal d // use this to calculate the derivatives at this point. // std::transform(std::begin(current), std::end(current), std::begin(half_update), // std::begin(result2), std::plus{}); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { result2[i] = current[i] + half_update[i]; } @@ -639,7 +639,7 @@ BoutReal AdamsBashforthSolver::take_step(const BoutReal timeIn, const BoutReal d // "full" two half step half_update. Rather than using result2 we just replace // result here as we want to use this smaller step result if (followHighOrder) { - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { result[i] = current[i] + half_update[i]; } diff --git a/src/solver/impls/adams_bashforth/adams_bashforth.hxx b/src/solver/impls/adams_bashforth/adams_bashforth.hxx index ad8e77ed1c..60b3b2b05e 100644 --- a/src/solver/impls/adams_bashforth/adams_bashforth.hxx +++ b/src/solver/impls/adams_bashforth/adams_bashforth.hxx @@ -25,8 +25,8 @@ class AdamsBashforthSolver; -#ifndef __ADAMSBASHFORTH_SOLVER_H__ -#define __ADAMSBASHFORTH_SOLVER_H__ +#ifndef BOUT_ADAMSBASHFORTH_SOLVER_H +#define BOUT_ADAMSBASHFORTH_SOLVER_H #include #include @@ -96,4 +96,4 @@ private: int nlocal, neq; // Number of variables on local processor and in total }; -#endif // __ADAMSBASHFORTH_SOLVER_H__ +#endif // BOUT_ADAMSBASHFORTH_SOLVER_H diff --git a/src/solver/impls/adams_bashforth/makefile b/src/solver/impls/adams_bashforth/makefile deleted file mode 100644 index 5349d55f48..0000000000 --- a/src/solver/impls/adams_bashforth/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = adams_bashforth.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/arkode/arkode.cxx b/src/solver/impls/arkode/arkode.cxx index 13e0dd817e..440f8f54f1 100644 --- a/src/solver/impls/arkode/arkode.cxx +++ b/src/solver/impls/arkode/arkode.cxx @@ -4,9 +4,7 @@ * NOTE: ARKode is still in beta testing so use with cautious optimism * ************************************************************************** - * Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu - * - * Contact: Nick Walkden, nick.walkden@ccfe.ac.uk + * Copyright 2010-2024 BOUT++ contributors * * This file is part of BOUT++. * @@ -31,6 +29,7 @@ #if BOUT_HAS_ARKODE +#include "bout/bout_enum_class.hxx" #include "bout/boutcomm.hxx" #include "bout/boutexception.hxx" #include "bout/field3d.hxx" @@ -41,17 +40,7 @@ #include "bout/unused.hxx" #include "bout/utils.hxx" -#if SUNDIALS_VERSION_MAJOR >= 4 #include -#else -#include -#if SUNDIALS_VERSION_MAJOR >= 3 -#include -#else -#include -#endif -#endif - #include #include #include @@ -61,110 +50,21 @@ class Field2D; -#define ZERO RCONST(0.) -#define ONE RCONST(1.0) +// NOLINTBEGIN(readability-identifier-length) +namespace { +int arkode_rhs_explicit(BoutReal t, N_Vector u, N_Vector du, void* user_data); +int arkode_rhs_implicit(BoutReal t, N_Vector u, N_Vector du, void* user_data); +int arkode_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data); -#ifndef ARKODEINT -#if SUNDIALS_VERSION_MAJOR < 3 -using ARKODEINT = bout::utils::function_traits::arg_t<0>; -#else -using ARKODEINT = sunindextype; -#endif -#endif +int arkode_bbd_rhs(sunindextype Nlocal, BoutReal t, N_Vector u, N_Vector du, + void* user_data); +int arkode_pre(BoutReal t, N_Vector yy, N_Vector yp, N_Vector rvec, N_Vector zvec, + BoutReal gamma, BoutReal delta, int lr, void* user_data); -static int arkode_rhs_explicit(BoutReal t, N_Vector u, N_Vector du, void* user_data); -static int arkode_rhs_implicit(BoutReal t, N_Vector u, N_Vector du, void* user_data); -static int arkode_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data); - -static int arkode_bbd_rhs(ARKODEINT Nlocal, BoutReal t, N_Vector u, N_Vector du, - void* user_data); -static int arkode_pre(BoutReal t, N_Vector yy, N_Vector yp, N_Vector rvec, N_Vector zvec, - BoutReal gamma, BoutReal delta, int lr, void* user_data); -#if SUNDIALS_VERSION_MAJOR < 3 -// Shim for earlier versions -inline static int arkode_pre_shim(BoutReal t, N_Vector yy, N_Vector yp, N_Vector rvec, - N_Vector zvec, BoutReal gamma, BoutReal delta, int lr, - void* user_data, N_Vector UNUSED(tmp)) { - return arkode_pre(t, yy, yp, rvec, zvec, gamma, delta, lr, user_data); -} -#else -// Alias for newer versions -constexpr auto& arkode_pre_shim = arkode_pre; -#endif - -static int arkode_jac(N_Vector v, N_Vector Jv, realtype t, N_Vector y, N_Vector fy, - void* user_data, N_Vector tmp); -#if SUNDIALS_VERSION_MAJOR < 4 -// Shim for earlier versions -inline int ARKStepSetJacTimes(void* arkode_mem, std::nullptr_t, - ARKSpilsJacTimesVecFn jtimes) { -#if SUNDIALS_VERSION_MAJOR < 3 - return ARKSpilsSetJacTimesVecFn(arkode_mem, jtimes); -#else - return ARKSpilsSetJacTimes(arkode_mem, nullptr, jtimes); -#endif -} -#endif - -#if SUNDIALS_VERSION_MAJOR < 4 -void* ARKStepCreate(ARKRhsFn fe, ARKRhsFn fi, BoutReal t0, N_Vector y0) { - auto arkode_mem = ARKodeCreate(); - - if (arkode_mem == nullptr) { - throw BoutException("ARKodeCreate failed\n"); - } - if (ARKodeInit(arkode_mem, fe, fi, t0, y0) != ARK_SUCCESS) { - throw BoutException("ARKodeInit failed\n"); - } - return arkode_mem; -} - -#if SUNDIALS_VERSION_MAJOR == 3 -int ARKStepSetLinearSolver(void* arkode_mem, SUNLinearSolver LS, std::nullptr_t) { - return ARKSpilsSetLinearSolver(arkode_mem, LS); -} -#endif - -// Aliases for older versions -// In SUNDIALS 4, ARKode has become ARKStep, hence all the renames -constexpr auto& ARKStepEvolve = ARKode; -constexpr auto& ARKStepFree = ARKodeFree; -constexpr auto& ARKStepGetCurrentTime = ARKodeGetCurrentTime; -constexpr auto& ARKStepGetDky = ARKodeGetDky; -constexpr auto& ARKStepGetLastStep = ARKodeGetLastStep; -constexpr auto& ARKStepGetNumLinIters = ARKSpilsGetNumLinIters; -constexpr auto& ARKStepGetNumNonlinSolvIters = ARKodeGetNumNonlinSolvIters; -constexpr auto& ARKStepGetNumPrecEvals = ARKSpilsGetNumPrecEvals; -constexpr auto& ARKStepGetNumRhsEvals = ARKodeGetNumRhsEvals; -constexpr auto& ARKStepGetNumSteps = ARKodeGetNumSteps; -constexpr auto& ARKStepReInit = ARKodeReInit; -constexpr auto& ARKStepSStolerances = ARKodeSStolerances; -constexpr auto& ARKStepSVtolerances = ARKodeSVtolerances; -constexpr auto& ARKStepSetAdaptivityMethod = ARKodeSetAdaptivityMethod; -constexpr auto& ARKStepSetCFLFraction = ARKodeSetCFLFraction; -constexpr auto& ARKStepSetEpsLin = ARKSpilsSetEpsLin; -constexpr auto& ARKStepSetExplicit = ARKodeSetExplicit; -constexpr auto& ARKStepSetFixedPoint = ARKodeSetFixedPoint; -constexpr auto& ARKStepSetFixedStep = ARKodeSetFixedStep; -constexpr auto& ARKStepSetImEx = ARKodeSetImEx; -constexpr auto& ARKStepSetImplicit = ARKodeSetImplicit; -constexpr auto& ARKStepSetInitStep = ARKodeSetInitStep; -constexpr auto& ARKStepSetLinear = ARKodeSetLinear; -constexpr auto& ARKStepSetMaxNumSteps = ARKodeSetMaxNumSteps; -constexpr auto& ARKStepSetMaxStep = ARKodeSetMaxStep; -constexpr auto& ARKStepSetMinStep = ARKodeSetMinStep; -constexpr auto& ARKStepSetOptimalParams = ARKodeSetOptimalParams; -constexpr auto& ARKStepSetOrder = ARKodeSetOrder; -constexpr auto& ARKStepSetPreconditioner = ARKSpilsSetPreconditioner; -constexpr auto& ARKStepSetUserData = ARKodeSetUserData; -#endif - -#if SUNDIALS_VERSION_MAJOR < 6 -void* ARKStepCreate(ARKRhsFn fe, ARKRhsFn fi, BoutReal t0, N_Vector y0, - MAYBE_UNUSED(SUNContext context)) { - return ARKStepCreate(fe, fi, t0, y0); -} -#endif +int arkode_jac(N_Vector v, N_Vector Jv, BoutReal t, N_Vector y, N_Vector fy, + void* user_data, N_Vector tmp); +} // namespace +// NOLINTEND(readability-identifier-length) ArkodeSolver::ArkodeSolver(Options* opts) : Solver(opts), diagnose((*options)["diagnose"] @@ -173,11 +73,10 @@ ArkodeSolver::ArkodeSolver(Options* opts) mxsteps((*options)["mxstep"] .doc("Maximum number of steps to take between outputs") .withDefault(500)), - imex((*options)["imex"].doc("Use ImEx capability").withDefault(true)), - solve_explicit( - (*options)["explicit"].doc("Solve only explicit part").withDefault(true)), - solve_implicit( - (*options)["implicit"].doc("Solve only implicit part").withDefault(true)), + treatment((*options)["treatment"] + .doc("Use default capability (imex) or provide a specific treatment: " + "implicit or explicit") + .withDefault(Treatment::ImEx)), set_linear( (*options)["set_linear"] .doc("Use linear implicit solver (only evaluates jacobian inversion once)") @@ -187,14 +86,22 @@ ArkodeSolver::ArkodeSolver(Options* opts) "not recommended except for code comparison") .withDefault(false)), order((*options)["order"].doc("Order of internal step").withDefault(4)), +#if SUNDIALS_TABLE_BY_NAME_SUPPORT + implicit_table((*options)["implicit_table"] + .doc("Name of the implicit Butcher table") + .withDefault("")), + explicit_table((*options)["explicit_table"] + .doc("Name of the explicit Butcher table") + .withDefault("")), +#endif cfl_frac((*options)["cfl_frac"] .doc("Fraction of the estimated explicitly stable step to use") .withDefault(-1.0)), - adap_method((*options)["adap_method"] - .doc("Set timestep adaptivity function: 0 -> PID adaptivity " - "(default); 1 -> PI; 2 -> I; 3 -> explicit Gustafsson; 4 -> " - "implicit Gustafsson; 5 -> ImEx Gustafsson;") - .withDefault(0)), + adap_method( + (*options)["adap_method"] + .doc("Set timestep adaptivity function: pid, pi, i, explicit_gustafsson, " + "implicit_gustafsson, imex_gustafsson.") + .withDefault(AdapMethod::PID)), abstol((*options)["atol"].doc("Absolute tolerance").withDefault(1.0e-12)), reltol((*options)["rtol"].doc("Relative tolerance").withDefault(1.0e-5)), use_vector_abstol((*options)["use_vector_abstol"] @@ -226,7 +133,7 @@ ArkodeSolver::ArkodeSolver(Options* opts) .withDefault(false)), optimize( (*options)["optimize"].doc("Use ARKode optimal parameters").withDefault(false)), - suncontext(static_cast(&BoutComm::get())) { + suncontext(createSUNContext(BoutComm::get())) { has_constraints = false; // This solver doesn't have constraints // Add diagnostics to output @@ -243,10 +150,14 @@ ArkodeSolver::ArkodeSolver(Options* opts) } ArkodeSolver::~ArkodeSolver() { - N_VDestroy_Parallel(uvec); + N_VDestroy(uvec); ARKStepFree(&arkode_mem); SUNLinSolFree(sun_solver); SUNNonlinSolFree(nonlinear_solver); + +#if SUNDIALS_CONTROLLER_SUPPORT + SUNAdaptController_Destroy(controller); +#endif } /************************************************************************** @@ -274,50 +185,55 @@ int ArkodeSolver::init() { n2Dvars(), neq, local_N); // Allocate memory - if ((uvec = N_VNew_Parallel(BoutComm::get(), local_N, neq, suncontext)) == nullptr) { + uvec = callWithSUNContext(N_VNew_Parallel, suncontext, BoutComm::get(), local_N, neq); + if (uvec == nullptr) { throw BoutException("SUNDIALS memory allocation failed\n"); } // Put the variables into uvec - save_vars(NV_DATA_P(uvec)); - - ASSERT1(solve_explicit or solve_implicit); - - const auto& explicit_rhs = [this]() { - if (imex) { - return arkode_rhs_explicit; - } else { - return solve_explicit ? arkode_rhs : nullptr; - } - }(); - const auto& implicit_rhs = [this]() { - if (imex) { - return arkode_rhs_implicit; - } else { - return solve_implicit ? arkode_rhs : nullptr; - } - }(); - - if ((arkode_mem = ARKStepCreate(explicit_rhs, implicit_rhs, simtime, uvec, suncontext)) - == nullptr) { + save_vars(N_VGetArrayPointer(uvec)); + + switch (treatment) { + case Treatment::ImEx: + arkode_mem = callWithSUNContext(ARKStepCreate, suncontext, arkode_rhs_explicit, + arkode_rhs_implicit, simtime, uvec); + break; + case Treatment::Explicit: + arkode_mem = + callWithSUNContext(ARKStepCreate, suncontext, arkode_rhs, nullptr, simtime, uvec); + break; + case Treatment::Implicit: + arkode_mem = + callWithSUNContext(ARKStepCreate, suncontext, nullptr, arkode_rhs, simtime, uvec); + break; + default: + throw BoutException("Invalid treatment: {}\n", toString(treatment)); + } + if (arkode_mem == nullptr) { throw BoutException("ARKStepCreate failed\n"); } - if (imex and solve_explicit and solve_implicit) { + switch (treatment) { + case Treatment::ImEx: output_info.write("\tUsing ARKode ImEx solver \n"); if (ARKStepSetImEx(arkode_mem) != ARK_SUCCESS) { throw BoutException("ARKStepSetImEx failed\n"); } - } else if (solve_explicit) { + break; + case Treatment::Explicit: output_info.write("\tUsing ARKStep Explicit solver \n"); if (ARKStepSetExplicit(arkode_mem) != ARK_SUCCESS) { throw BoutException("ARKStepSetExplicit failed\n"); } - } else { + break; + case Treatment::Implicit: output_info.write("\tUsing ARKStep Implicit solver \n"); if (ARKStepSetImplicit(arkode_mem) != ARK_SUCCESS) { throw BoutException("ARKStepSetImplicit failed\n"); } + break; + default: + throw BoutException("Invalid treatment: {}\n", toString(treatment)); } // For callbacks, need pointer to solver object @@ -325,11 +241,8 @@ int ArkodeSolver::init() { throw BoutException("ARKStepSetUserData failed\n"); } - if (set_linear) { - output.write("\tSetting ARKStep implicit solver to Linear\n"); - if (ARKStepSetLinear(arkode_mem, 1) != ARK_SUCCESS) { - throw BoutException("ARKStepSetLinear failed\n"); - } + if (ARKStepSetLinear(arkode_mem, set_linear) != ARK_SUCCESS) { + throw BoutException("ARKStepSetLinear failed\n"); } if (fixed_step) { @@ -344,20 +257,91 @@ int ArkodeSolver::init() { throw BoutException("ARKStepSetOrder failed\n"); } +#if SUNDIALS_TABLE_BY_NAME_SUPPORT + if (!implicit_table.empty() || !explicit_table.empty()) { + if (ARKStepSetTableName( + arkode_mem, + implicit_table.empty() ? "ARKODE_DIRK_NONE" : implicit_table.c_str(), + explicit_table.empty() ? "ARKODE_ERK_NONE" : explicit_table.c_str()) + != ARK_SUCCESS) { + throw BoutException("ARKStepSetTableName failed\n"); + } + } +#endif + if (ARKStepSetCFLFraction(arkode_mem, cfl_frac) != ARK_SUCCESS) { throw BoutException("ARKStepSetCFLFraction failed\n"); } - if (ARKStepSetAdaptivityMethod(arkode_mem, adap_method, 1, 1, nullptr) != ARK_SUCCESS) { +#if SUNDIALS_CONTROLLER_SUPPORT + switch (adap_method) { + case AdapMethod::PID: + controller = SUNAdaptController_PID(suncontext); + break; + case AdapMethod::PI: + controller = SUNAdaptController_PI(suncontext); + break; + case AdapMethod::I: + controller = SUNAdaptController_I(suncontext); + break; + case AdapMethod::Explicit_Gustafsson: + controller = SUNAdaptController_ExpGus(suncontext); + break; + case AdapMethod::Implicit_Gustafsson: + controller = SUNAdaptController_ImpGus(suncontext); + break; + case AdapMethod::ImEx_Gustafsson: + controller = SUNAdaptController_ImExGus(suncontext); + break; + default: + throw BoutException("Invalid adap_method\n"); + } + + if (ARKStepSetAdaptController(arkode_mem, controller) != ARK_SUCCESS) { + throw BoutException("ARKStepSetAdaptController failed\n"); + } + + if (ARKStepSetAdaptivityAdjustment(arkode_mem, 0) != ARK_SUCCESS) { + throw BoutException("ARKStepSetAdaptivityAdjustment failed\n"); + } +#else + int adap_method_int; + // Could cast to underlying integer, but this is more explicit + switch (adap_method) { + case AdapMethod::PID: + adap_method_int = 0; + break; + case AdapMethod::PI: + adap_method_int = 1; + break; + case AdapMethod::I: + adap_method_int = 2; + break; + case AdapMethod::Explicit_Gustafsson: + adap_method_int = 3; + break; + case AdapMethod::Implicit_Gustafsson: + adap_method_int = 4; + break; + case AdapMethod::ImEx_Gustafsson: + adap_method_int = 5; + break; + default: + throw BoutException("Invalid adap_method\n"); + } + + if (ARKStepSetAdaptivityMethod(arkode_mem, adap_method_int, 1, 1, nullptr) + != ARK_SUCCESS) { throw BoutException("ARKStepSetAdaptivityMethod failed\n"); } +#endif if (use_vector_abstol) { std::vector f2dtols; f2dtols.reserve(f2d.size()); std::transform(begin(f2d), end(f2d), std::back_inserter(f2dtols), [abstol = abstol](const VarStr& f2) { - auto f2_options = Options::root()[f2.name]; + auto& f2_options = Options::root()[f2.name]; const auto wrong_name = f2_options.isSet("abstol"); if (wrong_name) { output_warn << "WARNING: Option 'abstol' for field " << f2.name @@ -374,18 +358,18 @@ int ArkodeSolver::init() { return Options::root()[f3.name]["atol"].withDefault(abstol); }); - N_Vector abstolvec = N_VNew_Parallel(BoutComm::get(), local_N, neq, suncontext); + N_Vector abstolvec = N_VClone(uvec); if (abstolvec == nullptr) { throw BoutException("SUNDIALS memory allocation (abstol vector) failed\n"); } - set_abstol_values(NV_DATA_P(abstolvec), f2dtols, f3dtols); + set_abstol_values(N_VGetArrayPointer(abstolvec), f2dtols, f3dtols); if (ARKStepSVtolerances(arkode_mem, reltol, abstolvec) != ARK_SUCCESS) { throw BoutException("ARKStepSVtolerances failed\n"); } - N_VDestroy_Parallel(abstolvec); + N_VDestroy(abstolvec); } else { if (ARKStepSStolerances(arkode_mem, reltol, abstol) != ARK_SUCCESS) { throw BoutException("ARKStepSStolerances failed\n"); @@ -414,130 +398,94 @@ int ArkodeSolver::init() { } } - // ARKStepSetPredictorMethod(arkode_mem,4); - -#if SUNDIALS_VERSION_MAJOR < 4 - if (fixed_point) { - output.write("\tUsing accelerated fixed point solver\n"); - if (ARKodeSetFixedPoint(arkode_mem, 3.0)) { - throw BoutException("ARKodeSetFixedPoint failed\n"); - } - } else { - output.write("\tUsing Newton iteration\n"); - if (ARKodeSetNewton(arkode_mem)) { - throw BoutException("ARKodeSetNewton failed\n"); - } - } -#else - if (fixed_point) { - output.write("\tUsing accelerated fixed point solver\n"); - if ((nonlinear_solver = SUNNonlinSol_FixedPoint(uvec, 3, suncontext)) == nullptr) { - throw BoutException("Creating SUNDIALS fixed point nonlinear solver failed\n"); - } - } else { - output.write("\tUsing Newton iteration\n"); - if ((nonlinear_solver = SUNNonlinSol_Newton(uvec, suncontext)) == nullptr) { - throw BoutException("Creating SUNDIALS Newton nonlinear solver failed\n"); - } - } - if (ARKStepSetNonlinearSolver(arkode_mem, nonlinear_solver) != ARK_SUCCESS) { - throw BoutException("ARKStepSetNonlinearSolver failed\n"); - } -#endif - - /// Set Preconditioner - if (use_precon) { - const int prectype = rightprec ? SUN_PREC_RIGHT : SUN_PREC_LEFT; - -#if SUNDIALS_VERSION_MAJOR >= 3 - if ((sun_solver = SUNLinSol_SPGMR(uvec, prectype, maxl, suncontext)) == nullptr) { - throw BoutException("Creating SUNDIALS linear solver failed\n"); - } - if (ARKStepSetLinearSolver(arkode_mem, sun_solver, nullptr) != ARK_SUCCESS) { - throw BoutException("ARKStepSetLinearSolver failed\n"); - } -#else - if (ARKSpgmr(arkode_mem, prectype, maxl) != ARKSPILS_SUCCESS) { - throw BoutException("ARKSpgmr failed\n"); - } -#endif - - if (!hasPreconditioner()) { - output.write("\tUsing BBD preconditioner\n"); - - /// Get options - // Compute band_width_default from actually added fields, to allow for multiple - // Mesh objects - // - // Previous implementation was equivalent to: - // int MXSUB = mesh->xend - mesh->xstart + 1; - // int band_width_default = n3Dvars()*(MXSUB+2); - const int band_width_default = std::accumulate( - begin(f3d), end(f3d), 0, [](int a, const VarStr& fvar) { - Mesh* localmesh = fvar.var->getMesh(); - return a + localmesh->xend - localmesh->xstart + 3; - }); - - const auto mudq = (*options)["mudq"] - .doc("Upper half-bandwidth to be used in the difference " - "quotient Jacobian approximation") - .withDefault(band_width_default); - const auto mldq = (*options)["mldq"] - .doc("Lower half-bandwidth to be used in the difference " - "quotient Jacobian approximation") - .withDefault(band_width_default); - const auto mukeep = (*options)["mukeep"] - .doc("Upper half-bandwidth of the retained banded " - "approximate Jacobian block") - .withDefault(n3Dvars() + n2Dvars()); - const auto mlkeep = (*options)["mlkeep"] - .doc("Lower half-bandwidth of the retained banded " - "approximate Jacobian block") - .withDefault(n3Dvars() + n2Dvars()); - - if (ARKBBDPrecInit(arkode_mem, local_N, mudq, mldq, mukeep, mlkeep, ZERO, - arkode_bbd_rhs, nullptr) - != ARK_SUCCESS) { - throw BoutException("ARKBBDPrecInit failed\n"); + if (treatment == Treatment::ImEx or treatment == Treatment::Implicit) { + if (fixed_point) { + output.write("\tUsing accelerated fixed point solver\n"); + nonlinear_solver = callWithSUNContext(SUNNonlinSol_FixedPoint, suncontext, uvec, 3); + if (nonlinear_solver == nullptr) { + throw BoutException("Creating SUNDIALS fixed point nonlinear solver failed\n"); + } + if (ARKStepSetNonlinearSolver(arkode_mem, nonlinear_solver) != ARK_SUCCESS) { + throw BoutException("ARKStepSetNonlinearSolver failed\n"); } - } else { - output.write("\tUsing user-supplied preconditioner\n"); + output.write("\tUsing Newton iteration\n"); - if (ARKStepSetPreconditioner(arkode_mem, nullptr, arkode_pre_shim) != ARK_SUCCESS) { - throw BoutException("ARKStepSetPreconditioner failed\n"); + const auto prectype = + use_precon ? (rightprec ? SUN_PREC_RIGHT : SUN_PREC_LEFT) : SUN_PREC_NONE; + sun_solver = callWithSUNContext(SUNLinSol_SPGMR, suncontext, uvec, prectype, maxl); + if (sun_solver == nullptr) { + throw BoutException("Creating SUNDIALS linear solver failed\n"); + } + if (ARKStepSetLinearSolver(arkode_mem, sun_solver, nullptr) != ARKLS_SUCCESS) { + throw BoutException("ARKStepSetLinearSolver failed\n"); } - } - } else { - // Not using preconditioning - - output.write("\tNo preconditioning\n"); -#if SUNDIALS_VERSION_MAJOR >= 3 - if ((sun_solver = SUNLinSol_SPGMR(uvec, SUN_PREC_NONE, maxl, suncontext)) - == nullptr) { - throw BoutException("Creating SUNDIALS linear solver failed\n"); - } - if (ARKStepSetLinearSolver(arkode_mem, sun_solver, nullptr) != ARK_SUCCESS) { - throw BoutException("ARKStepSetLinearSolver failed\n"); - } -#else - if (ARKSpgmr(arkode_mem, SUN_PREC_NONE, maxl) != ARKSPILS_SUCCESS) { - throw BoutException("ARKSpgmr failed\n"); + /// Set Preconditioner + if (use_precon) { + if (hasPreconditioner()) { + output.write("\tUsing user-supplied preconditioner\n"); + + if (ARKStepSetPreconditioner(arkode_mem, nullptr, arkode_pre) + != ARKLS_SUCCESS) { + throw BoutException("ARKStepSetPreconditioner failed\n"); + } + } else { + output.write("\tUsing BBD preconditioner\n"); + + /// Get options + // Compute band_width_default from actually added fields, to allow for multiple + // Mesh objects + // + // Previous implementation was equivalent to: + // int MXSUB = mesh->xend - mesh->xstart + 1; + // int band_width_default = n3Dvars()*(MXSUB+2); + const int band_width_default = std::accumulate( + begin(f3d), end(f3d), 0, [](int acc, const VarStr& fvar) { + Mesh* localmesh = fvar.var->getMesh(); + return acc + localmesh->xend - localmesh->xstart + 3; + }); + + const auto mudq = (*options)["mudq"] + .doc("Upper half-bandwidth to be used in the difference " + "quotient Jacobian approximation") + .withDefault(band_width_default); + const auto mldq = (*options)["mldq"] + .doc("Lower half-bandwidth to be used in the difference " + "quotient Jacobian approximation") + .withDefault(band_width_default); + const auto mukeep = (*options)["mukeep"] + .doc("Upper half-bandwidth of the retained banded " + "approximate Jacobian block") + .withDefault(n3Dvars() + n2Dvars()); + const auto mlkeep = (*options)["mlkeep"] + .doc("Lower half-bandwidth of the retained banded " + "approximate Jacobian block") + .withDefault(n3Dvars() + n2Dvars()); + + if (ARKBBDPrecInit(arkode_mem, local_N, mudq, mldq, mukeep, mlkeep, 0, + arkode_bbd_rhs, nullptr) + != ARKLS_SUCCESS) { + throw BoutException("ARKBBDPrecInit failed\n"); + } + } + } else { + // Not using preconditioning + output.write("\tNo preconditioning\n"); + } } -#endif - } - /// Set Jacobian-vector multiplication function + /// Set Jacobian-vector multiplication function - if (use_jacobian and hasJacobian()) { - output.write("\tUsing user-supplied Jacobian function\n"); + if (use_jacobian and hasJacobian()) { + output.write("\tUsing user-supplied Jacobian function\n"); - if (ARKStepSetJacTimes(arkode_mem, nullptr, arkode_jac) != ARK_SUCCESS) { - throw BoutException("ARKStepSetJacTimesVecFn failed\n"); + if (ARKStepSetJacTimes(arkode_mem, nullptr, arkode_jac) != ARKLS_SUCCESS) { + throw BoutException("ARKStepSetJacTimes failed\n"); + } + } else { + output.write("\tUsing difference quotient approximation for Jacobian\n"); } - } else { - output.write("\tUsing difference quotient approximation for Jacobian\n"); } if (optimize) { @@ -580,24 +528,27 @@ int ArkodeSolver::run() { ARKStepGetNumRhsEvals(arkode_mem, &temp_long_int, &temp_long_int2); nfe_evals = int(temp_long_int); nfi_evals = int(temp_long_int2); - ARKStepGetNumNonlinSolvIters(arkode_mem, &temp_long_int); - nniters = int(temp_long_int); - ARKStepGetNumPrecEvals(arkode_mem, &temp_long_int); - npevals = int(temp_long_int); - ARKStepGetNumLinIters(arkode_mem, &temp_long_int); - nliters = int(temp_long_int); + if (treatment == Treatment::ImEx or treatment == Treatment::Implicit) { + ARKStepGetNumNonlinSolvIters(arkode_mem, &temp_long_int); + nniters = int(temp_long_int); + ARKStepGetNumPrecEvals(arkode_mem, &temp_long_int); + npevals = int(temp_long_int); + ARKStepGetNumLinIters(arkode_mem, &temp_long_int); + nliters = int(temp_long_int); + } if (diagnose) { output.write("\nARKODE: nsteps {:d}, nfe_evals {:d}, nfi_evals {:d}, nniters {:d}, " "npevals {:d}, nliters {:d}\n", nsteps, nfe_evals, nfi_evals, nniters, npevals, nliters); - - output.write(" -> Newton iterations per step: {:e}\n", - static_cast(nniters) / static_cast(nsteps)); - output.write(" -> Linear iterations per Newton iteration: {:e}\n", - static_cast(nliters) / static_cast(nniters)); - output.write(" -> Preconditioner evaluations per Newton: {:e}\n", - static_cast(npevals) / static_cast(nniters)); + if (treatment == Treatment::ImEx or treatment == Treatment::Implicit) { + output.write(" -> Newton iterations per step: {:e}\n", + static_cast(nniters) / static_cast(nsteps)); + output.write(" -> Linear iterations per Newton iteration: {:e}\n", + static_cast(nliters) / static_cast(nniters)); + output.write(" -> Preconditioner evaluations per Newton: {:e}\n", + static_cast(npevals) / static_cast(nniters)); + } } if (call_monitors(simtime, i, getNumberOutputSteps())) { @@ -645,7 +596,7 @@ BoutReal ArkodeSolver::run(BoutReal tout) { } // Copy variables - load_vars(NV_DATA_P(uvec)); + load_vars(N_VGetArrayPointer(uvec)); // Call rhs function to get extra variables at this time run_rhs(simtime); // run_diffusive(simtime); @@ -718,8 +669,8 @@ void ArkodeSolver::pre(BoutReal t, BoutReal gamma, BoutReal delta, BoutReal* uda if (!hasPreconditioner()) { // Identity (but should never happen) - const int N = NV_LOCLENGTH_P(uvec); - std::copy(rvec, rvec + N, zvec); + const auto length = N_VGetLocalLength_Parallel(uvec); + std::copy(rvec, rvec + length, zvec); return; } @@ -766,10 +717,12 @@ void ArkodeSolver::jac(BoutReal t, BoutReal* ydata, BoutReal* vdata, BoutReal* J * ARKODE explicit RHS functions **************************************************************************/ -static int arkode_rhs_explicit(BoutReal t, N_Vector u, N_Vector du, void* user_data) { +// NOLINTBEGIN(readability-identifier-length) +namespace { +int arkode_rhs_explicit(BoutReal t, N_Vector u, N_Vector du, void* user_data) { - BoutReal* udata = NV_DATA_P(u); - BoutReal* dudata = NV_DATA_P(du); + BoutReal* udata = N_VGetArrayPointer(u); + BoutReal* dudata = N_VGetArrayPointer(du); auto* s = static_cast(user_data); @@ -782,10 +735,10 @@ static int arkode_rhs_explicit(BoutReal t, N_Vector u, N_Vector du, void* user_d return 0; } -static int arkode_rhs_implicit(BoutReal t, N_Vector u, N_Vector du, void* user_data) { +int arkode_rhs_implicit(BoutReal t, N_Vector u, N_Vector du, void* user_data) { - BoutReal* udata = NV_DATA_P(u); - BoutReal* dudata = NV_DATA_P(du); + BoutReal* udata = N_VGetArrayPointer(u); + BoutReal* dudata = N_VGetArrayPointer(du); auto* s = static_cast(user_data); @@ -798,10 +751,10 @@ static int arkode_rhs_implicit(BoutReal t, N_Vector u, N_Vector du, void* user_d return 0; } -static int arkode_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data) { +int arkode_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data) { - BoutReal* udata = NV_DATA_P(u); - BoutReal* dudata = NV_DATA_P(du); + BoutReal* udata = N_VGetArrayPointer(u); + BoutReal* dudata = N_VGetArrayPointer(du); auto* s = static_cast(user_data); @@ -815,18 +768,17 @@ static int arkode_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data) { } /// RHS function for BBD preconditioner -static int arkode_bbd_rhs(ARKODEINT UNUSED(Nlocal), BoutReal t, N_Vector u, N_Vector du, - void* user_data) { +int arkode_bbd_rhs(sunindextype UNUSED(Nlocal), BoutReal t, N_Vector u, N_Vector du, + void* user_data) { return arkode_rhs_implicit(t, u, du, user_data); } /// Preconditioner function -static int arkode_pre(BoutReal t, N_Vector yy, N_Vector UNUSED(yp), N_Vector rvec, - N_Vector zvec, BoutReal gamma, BoutReal delta, int UNUSED(lr), - void* user_data) { - BoutReal* udata = NV_DATA_P(yy); - BoutReal* rdata = NV_DATA_P(rvec); - BoutReal* zdata = NV_DATA_P(zvec); +int arkode_pre(BoutReal t, N_Vector yy, N_Vector UNUSED(yp), N_Vector rvec, N_Vector zvec, + BoutReal gamma, BoutReal delta, int UNUSED(lr), void* user_data) { + BoutReal* udata = N_VGetArrayPointer(yy); + BoutReal* rdata = N_VGetArrayPointer(rvec); + BoutReal* zdata = N_VGetArrayPointer(zvec); auto* s = static_cast(user_data); @@ -837,11 +789,11 @@ static int arkode_pre(BoutReal t, N_Vector yy, N_Vector UNUSED(yp), N_Vector rve } /// Jacobian-vector multiplication function -static int arkode_jac(N_Vector v, N_Vector Jv, realtype t, N_Vector y, - N_Vector UNUSED(fy), void* user_data, N_Vector UNUSED(tmp)) { - BoutReal* ydata = NV_DATA_P(y); ///< System state - BoutReal* vdata = NV_DATA_P(v); ///< Input vector - BoutReal* Jvdata = NV_DATA_P(Jv); ///< Jacobian*vector output +int arkode_jac(N_Vector v, N_Vector Jv, BoutReal t, N_Vector y, N_Vector UNUSED(fy), + void* user_data, N_Vector UNUSED(tmp)) { + BoutReal* ydata = N_VGetArrayPointer(y); ///< System state + BoutReal* vdata = N_VGetArrayPointer(v); ///< Input vector + BoutReal* Jvdata = N_VGetArrayPointer(Jv); ///< Jacobian*vector output auto* s = static_cast(user_data); @@ -849,6 +801,8 @@ static int arkode_jac(N_Vector v, N_Vector Jv, realtype t, N_Vector y, return 0; } +} // namespace +// NOLINTEND(readability-identifier-length) /************************************************************************** * vector abstol functions diff --git a/src/solver/impls/arkode/arkode.hxx b/src/solver/impls/arkode/arkode.hxx index afdce0b701..4050ed377f 100644 --- a/src/solver/impls/arkode/arkode.hxx +++ b/src/solver/impls/arkode/arkode.hxx @@ -5,9 +5,9 @@ * NOTE: Only one solver can currently be compiled in * ************************************************************************** - * Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu + * Copyright 2010-2024 BOUT++ contributors * - * Contact: Ben Dudson, bd512@york.ac.uk + * Contact: Ben Dudson, dudson2@llnl.gov * * This file is part of BOUT++. * @@ -26,8 +26,8 @@ * **************************************************************************/ -#ifndef __ARKODE_SOLVER_H__ -#define __ARKODE_SOLVER_H__ +#ifndef BOUT_ARKODE_SOLVER_H +#define BOUT_ARKODE_SOLVER_H #include "bout/build_config.hxx" #include "bout/solver.hxx" @@ -41,12 +41,17 @@ RegisterUnavailableSolver #else +#include "bout/bout_enum_class.hxx" #include "bout/bout_types.hxx" #include "bout/sundials_backports.hxx" #include #include +#if SUNDIALS_CONTROLLER_SUPPORT +#include +#endif + #include class ArkodeSolver; @@ -56,6 +61,14 @@ namespace { RegisterSolver registersolverarkode("arkode"); } +// enum describing treatment of equations +// Note: Capitalized because `explicit` is a C++ reserved keyword +BOUT_ENUM_CLASS(Treatment, ImEx, Implicit, Explicit); + +// Adaptivity method +BOUT_ENUM_CLASS(AdapMethod, PID, PI, I, Explicit_Gustafsson, Implicit_Gustafsson, + ImEx_Gustafsson); + class ArkodeSolver : public Solver { public: explicit ArkodeSolver(Options* opts = nullptr); @@ -89,12 +102,8 @@ private: /// Maximum number of steps to take between outputs int mxsteps; - /// Use ImEx capability - bool imex; - /// Solve only explicit part - bool solve_explicit; - /// Solve only implicit part - bool solve_implicit; + /// Integrator treatment enum: IMEX, Implicit or Explicit + Treatment treatment; /// Use linear implicit solver (only evaluates jacobian inversion once) bool set_linear; /// Solve explicit portion in fixed timestep mode. NOTE: This is not recommended except @@ -102,16 +111,14 @@ private: bool fixed_step; /// Order of internal step int order; + /// Name of the implicit Butcher table + std::string implicit_table; + /// Name of the explicit Butcher table + std::string explicit_table; /// Fraction of the estimated explicitly stable step to use BoutReal cfl_frac; - /// Set timestep adaptivity function: - /// - 0: PID adaptivity (default) - /// - 1: PI - /// - 2: I - /// - 3: explicit Gustafsson - /// - 4: implicit Gustafsson - /// - 5: ImEx Gustafsson - int adap_method; + /// Timestep adaptivity function + AdapMethod adap_method; /// Absolute tolerance BoutReal abstol; /// Relative tolerance @@ -153,11 +160,15 @@ private: /// SPGMR solver structure SUNLinearSolver sun_solver{nullptr}; - /// Solver for functional iterations for Adams-Moulton + /// Solver for implicit stages SUNNonlinearSolver nonlinear_solver{nullptr}; +#if SUNDIALS_CONTROLLER_SUPPORT + /// Timestep controller + SUNAdaptController controller{nullptr}; +#endif /// Context for SUNDIALS memory allocations sundials::Context suncontext; }; #endif // BOUT_HAS_ARKODE -#endif // __ARKODE_SOLVER_H__ +#endif // BOUT_ARKODE_SOLVER_H diff --git a/src/solver/impls/arkode/makefile b/src/solver/impls/arkode/makefile deleted file mode 100644 index 3726417df3..0000000000 --- a/src/solver/impls/arkode/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = arkode.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/cvode/cvode.cxx b/src/solver/impls/cvode/cvode.cxx index 70eb3b8841..7137ce3304 100644 --- a/src/solver/impls/cvode/cvode.cxx +++ b/src/solver/impls/cvode/cvode.cxx @@ -3,9 +3,9 @@ * * ************************************************************************** - * Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu + * Copyright 2010-2024 BOUT++ contributors * - * Contact: Ben Dudson, bd512@york.ac.uk + * Contact: Ben Dudson, dudson2@llnl.gov * * This file is part of BOUT++. * @@ -44,16 +44,9 @@ #include "fmt/core.h" #include - -#if SUNDIALS_VERSION_MAJOR >= 3 -#include -#include -#else -#include -#endif - #include #include +#include #include #include @@ -61,67 +54,23 @@ class Field2D; -#define ZERO RCONST(0.) -#define ONE RCONST(1.0) - -#ifndef CVODEINT -#if SUNDIALS_VERSION_MAJOR < 3 -using CVODEINT = bout::utils::function_traits::arg_t<0>; -#else -using CVODEINT = sunindextype; -#endif -#endif - BOUT_ENUM_CLASS(positivity_constraint, none, positive, non_negative, negative, non_positive); -static int cvode_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data); -static int cvode_bbd_rhs(CVODEINT Nlocal, BoutReal t, N_Vector u, N_Vector du, - void* user_data); - -static int cvode_pre(BoutReal t, N_Vector yy, N_Vector yp, N_Vector rvec, N_Vector zvec, - BoutReal gamma, BoutReal delta, int lr, void* user_data); +// NOLINTBEGIN(readability-identifier-length) +namespace { +int cvode_linear_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data); +int cvode_nonlinear_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data); +int cvode_bbd_rhs(sunindextype Nlocal, BoutReal t, N_Vector u, N_Vector du, + void* user_data); -#if SUNDIALS_VERSION_MAJOR < 3 -// Shim for earlier versions -inline static int cvode_pre_shim(BoutReal t, N_Vector yy, N_Vector yp, N_Vector rvec, - N_Vector zvec, BoutReal gamma, BoutReal delta, int lr, - void* user_data, N_Vector UNUSED(tmp)) { - return cvode_pre(t, yy, yp, rvec, zvec, gamma, delta, lr, user_data); -} -#else -// Alias for newer versions -constexpr auto& cvode_pre_shim = cvode_pre; -#endif - -static int cvode_jac(N_Vector v, N_Vector Jv, realtype t, N_Vector y, N_Vector fy, - void* user_data, N_Vector tmp); - -#if SUNDIALS_VERSION_MAJOR < 3 -// Shim for earlier versions -inline int CVSpilsSetJacTimes(void* arkode_mem, std::nullptr_t, - CVSpilsJacTimesVecFn jtimes) { - return CVSpilsSetJacTimesVecFn(arkode_mem, jtimes); -} -#endif +int cvode_pre(BoutReal t, N_Vector yy, N_Vector yp, N_Vector rvec, N_Vector zvec, + BoutReal gamma, BoutReal delta, int lr, void* user_data); -#if SUNDIALS_VERSION_MAJOR >= 4 -// Shim for newer versions -constexpr auto CV_FUNCTIONAL = 0; -constexpr auto CV_NEWTON = 0; -#endif - -#if SUNDIALS_VERSION_MAJOR >= 3 -void* CVodeCreate(int lmm, MAYBE_UNUSED(int iter), MAYBE_UNUSED(SUNContext context)) { -#if SUNDIALS_VERSION_MAJOR == 3 - return CVodeCreate(lmm, iter); -#elif SUNDIALS_VERSION_MAJOR == 4 || SUNDIALS_VERSION_MAJOR == 5 - return CVodeCreate(lmm); -#else - return CVodeCreate(lmm, context); -#endif -} -#endif +int cvode_jac(N_Vector v, N_Vector Jv, BoutReal t, N_Vector y, N_Vector fy, + void* user_data, N_Vector tmp); +} // namespace +// NOLINTEND(readability-identifier-length) CvodeSolver::CvodeSolver(Options* opts) : Solver(opts), diagnose((*options)["diagnose"] @@ -135,7 +84,7 @@ CvodeSolver::CvodeSolver(Options* opts) .doc("Use functional iteration instead of Newton") .withDefault(adams_moulton)), max_order((*options)["cvode_max_order"] - .doc("Maximum order of method to use. < 0 means no limit.") + .doc("Maximum order of method to use. <= 0 means default limit.") .withDefault(-1)), stablimdet((*options)["cvode_stability_limit_detection"].withDefault(false)), abstol((*options)["atol"].doc("Absolute tolerance").withDefault(1.0e-12)), @@ -147,19 +96,18 @@ CvodeSolver::CvodeSolver(Options* opts) .doc("Maximum number of internal steps between outputs.") .withDefault(500)), max_timestep( - (*options)["max_timestep"].doc("Maximum time step size").withDefault(-1.0)), + (*options)["max_timestep"].doc("Maximum time step size").withDefault(0.0)), min_timestep( - (*options)["min_timestep"].doc("Minimum time step size").withDefault(-1.0)), + (*options)["min_timestep"].doc("Minimum time step size").withDefault(0.0)), start_timestep((*options)["start_timestep"] - .doc("Starting time step. < 0 then chosen by CVODE.") - .withDefault(-1.0)), + .doc("Starting time step. = 0 then chosen by CVODE.") + .withDefault(0.0)), mxorder((*options)["mxorder"].doc("Maximum order").withDefault(-1)), max_nonlinear_iterations( (*options)["max_nonlinear_iterations"] .doc("Maximum number of nonlinear iterations allowed by CVODE before " - "reducing " - "timestep. CVODE default (used if this option is negative) is 3.") - .withDefault(-1)), + "reducing timestep.") + .withDefault(3)), apply_positivity_constraints( (*options)["apply_positivity_constraints"] .doc("Use CVODE function CVodeSetConstraints to constrain variables - the " @@ -183,7 +131,7 @@ CvodeSolver::CvodeSolver(Options* opts) .doc("Factor by which the Krylov linear solver’s convergence test constant " "is reduced from the nonlinear solver test constant.") .withDefault(0.05)), - suncontext(static_cast(&BoutComm::get())) { + suncontext(createSUNContext(BoutComm::get())) { has_constraints = false; // This solver doesn't have constraints canReset = true; @@ -209,7 +157,7 @@ CvodeSolver::CvodeSolver(Options* opts) CvodeSolver::~CvodeSolver() { if (cvode_initialised) { - N_VDestroy_Parallel(uvec); + N_VDestroy(uvec); CVodeFree(&cvode_mem); SUNLinSolFree(sun_solver); SUNNonlinSolFree(nonlinear_solver); @@ -241,12 +189,13 @@ int CvodeSolver::init() { n3Dvars(), n2Dvars(), neq, local_N); // Allocate memory - if ((uvec = N_VNew_Parallel(BoutComm::get(), local_N, neq, suncontext)) == nullptr) { + uvec = callWithSUNContext(N_VNew_Parallel, suncontext, BoutComm::get(), local_N, neq); + if (uvec == nullptr) { throw BoutException("SUNDIALS memory allocation failed\n"); } // Put the variables into uvec - save_vars(NV_DATA_P(uvec)); + save_vars(N_VGetArrayPointer(uvec)); if (adams_moulton) { // By default use functional iteration for Adams-Moulton @@ -257,31 +206,43 @@ int CvodeSolver::init() { } const auto lmm = adams_moulton ? CV_ADAMS : CV_BDF; - const auto iter = func_iter ? CV_FUNCTIONAL : CV_NEWTON; - if ((cvode_mem = CVodeCreate(lmm, iter, suncontext)) == nullptr) { + cvode_mem = callWithSUNContext(CVodeCreate, suncontext, lmm); + if (cvode_mem == nullptr) { throw BoutException("CVodeCreate failed\n"); } // For callbacks, need pointer to solver object - if (CVodeSetUserData(cvode_mem, this) < 0) { + if (CVodeSetUserData(cvode_mem, this) != CV_SUCCESS) { throw BoutException("CVodeSetUserData failed\n"); } - if (CVodeInit(cvode_mem, cvode_rhs, simtime, uvec) < 0) { +#if SUNDIALS_VERSION_MAJOR >= 6 + // Set the default RHS to linear, then pass nonlinear rhs to NL solver + if (CVodeInit(cvode_mem, cvode_linear_rhs, simtime, uvec) != CV_SUCCESS) { + throw BoutException("CVodeInit failed\n"); + } +#else + if (CVodeInit(cvode_mem, cvode_nonlinear_rhs, simtime, uvec) != CV_SUCCESS) { throw BoutException("CVodeInit failed\n"); } +#endif + if (mxorder > 0) { + output_warn << "WARNING: Option 'mxorder' is deprecated. Please use " + "'cvode_max_order' instead\n"; + if (CVodeSetMaxOrd(cvode_mem, mxorder) != CV_SUCCESS) { + throw BoutException("CVodeSetMaxOrder failed\n"); + } + } if (max_order > 0) { - if (CVodeSetMaxOrd(cvode_mem, max_order) < 0) { + if (CVodeSetMaxOrd(cvode_mem, max_order) != CV_SUCCESS) { throw BoutException("CVodeSetMaxOrder failed\n"); } } - if (stablimdet) { - if (CVodeSetStabLimDet(cvode_mem, stablimdet) < 0) { - throw BoutException("CVodeSetStabLimDet failed\n"); - } + if (CVodeSetStabLimDet(cvode_mem, static_cast(stablimdet)) != CV_SUCCESS) { + throw BoutException("CVodeSetStabLimDet failed\n"); } if (use_vector_abstol) { @@ -289,7 +250,7 @@ int CvodeSolver::init() { f2dtols.reserve(f2d.size()); std::transform(begin(f2d), end(f2d), std::back_inserter(f2dtols), [this](const VarStr& f2) { - auto f2_options = Options::root()[f2.name]; + auto& f2_options = Options::root()[f2.name]; const auto wrong_name = f2_options.isSet("abstol"); if (wrong_name) { output_warn << "WARNING: Option 'abstol' for field " << f2.name @@ -306,94 +267,97 @@ int CvodeSolver::init() { return Options::root()[f3.name]["atol"].withDefault(abstol); }); - N_Vector abstolvec = N_VNew_Parallel(BoutComm::get(), local_N, neq, suncontext); + N_Vector abstolvec = N_VClone(uvec); if (abstolvec == nullptr) { throw BoutException("SUNDIALS memory allocation (abstol vector) failed\n"); } - set_vector_option_values(NV_DATA_P(abstolvec), f2dtols, f3dtols); + set_vector_option_values(N_VGetArrayPointer(abstolvec), f2dtols, f3dtols); - if (CVodeSVtolerances(cvode_mem, reltol, abstolvec) < 0) { + if (CVodeSVtolerances(cvode_mem, reltol, abstolvec) != CV_SUCCESS) { throw BoutException("CVodeSVtolerances failed\n"); } - N_VDestroy_Parallel(abstolvec); + N_VDestroy(abstolvec); } else { - if (CVodeSStolerances(cvode_mem, reltol, abstol) < 0) { + if (CVodeSStolerances(cvode_mem, reltol, abstol) != CV_SUCCESS) { throw BoutException("CVodeSStolerances failed\n"); } } - CVodeSetMaxNumSteps(cvode_mem, mxsteps); - - if (max_timestep > 0.0) { - CVodeSetMaxStep(cvode_mem, max_timestep); + if (CVodeSetMaxNumSteps(cvode_mem, mxsteps) != CV_SUCCESS) { + throw BoutException("CVodeSetMaxNumSteps failed\n"); } - if (min_timestep > 0.0) { - CVodeSetMinStep(cvode_mem, min_timestep); + if (CVodeSetMaxStep(cvode_mem, max_timestep) != CV_SUCCESS) { + throw BoutException("CVodeSetMaxStep failed\n"); } - if (start_timestep > 0.0) { - CVodeSetInitStep(cvode_mem, start_timestep); + if (CVodeSetMinStep(cvode_mem, min_timestep) != CV_SUCCESS) { + throw BoutException("CVodeSetMinStep failed\n"); } - if (mxorder > 0) { - CVodeSetMaxOrd(cvode_mem, mxorder); + if (CVodeSetInitStep(cvode_mem, start_timestep) != CV_SUCCESS) { + throw BoutException("CVodeSetInitStep failed\n"); } - if (max_nonlinear_iterations > 0) { - CVodeSetMaxNonlinIters(cvode_mem, max_nonlinear_iterations); + if (CVodeSetMaxNonlinIters(cvode_mem, max_nonlinear_iterations) != CV_SUCCESS) { + throw BoutException("CVodeSetMaxNonlinIters failed\n"); } -#if not(SUNDIALS_VERSION_MAJOR >= 3 and SUNDIALS_VERSION_MINOR >= 2) - if (apply_positivity_constraints) { - throw BoutException("The apply_positivity_constraints option is only available with " - "SUNDIALS>=3.2.0"); - } -#else if (apply_positivity_constraints) { auto f2d_constraints = create_constraints(f2d); auto f3d_constraints = create_constraints(f3d); - N_Vector constraints_vec = N_VNew_Parallel(BoutComm::get(), local_N, neq, suncontext); + N_Vector constraints_vec = N_VClone(uvec); if (constraints_vec == nullptr) { throw BoutException("SUNDIALS memory allocation (positivity constraints vector) " "failed\n"); } - set_vector_option_values(NV_DATA_P(constraints_vec), f2d_constraints, + set_vector_option_values(N_VGetArrayPointer(constraints_vec), f2d_constraints, f3d_constraints); - if (CVodeSetConstraints(cvode_mem, constraints_vec) < 0) { + if (CVodeSetConstraints(cvode_mem, constraints_vec) != CV_SUCCESS) { throw BoutException("CVodeSetConstraints failed\n"); } - N_VDestroy_Parallel(constraints_vec); + N_VDestroy(constraints_vec); } -#endif /// Newton method can include Preconditioners and Jacobian function - if (!func_iter) { + if (func_iter) { + output_info.write("\tUsing Functional iteration\n"); + nonlinear_solver = callWithSUNContext(SUNNonlinSol_FixedPoint, suncontext, uvec, 0); + if (nonlinear_solver == nullptr) { + throw BoutException("SUNNonlinSol_FixedPoint failed\n"); + } + + if (CVodeSetNonlinearSolver(cvode_mem, nonlinear_solver) != 0) { + throw BoutException("CVodeSetNonlinearSolver failed\n"); + } + } else { output_info.write("\tUsing Newton iteration\n"); TRACE("Setting preconditioner"); - if (use_precon) { - const int prectype = rightprec ? SUN_PREC_RIGHT : SUN_PREC_LEFT; -#if SUNDIALS_VERSION_MAJOR >= 3 - if ((sun_solver = SUNLinSol_SPGMR(uvec, prectype, maxl, suncontext)) == nullptr) { - throw BoutException("Creating SUNDIALS linear solver failed\n"); - } - if (CVSpilsSetLinearSolver(cvode_mem, sun_solver) != CV_SUCCESS) { - throw BoutException("CVSpilsSetLinearSolver failed\n"); - } -#else - if (CVSpgmr(cvode_mem, prectype, maxl) != CVSPILS_SUCCESS) { - throw BoutException("CVSpgmr failed\n"); - } -#endif + const auto prectype = + use_precon ? (rightprec ? SUN_PREC_RIGHT : SUN_PREC_LEFT) : SUN_PREC_NONE; + sun_solver = callWithSUNContext(SUNLinSol_SPGMR, suncontext, uvec, prectype, maxl); + if (sun_solver == nullptr) { + throw BoutException("Creating SUNDIALS linear solver failed\n"); + } + if (CVodeSetLinearSolver(cvode_mem, sun_solver, nullptr) != CVLS_SUCCESS) { + throw BoutException("CVodeSetLinearSolver failed\n"); + } + + if (use_precon) { + if (hasPreconditioner()) { + output_info.write("\tUsing user-supplied preconditioner\n"); - if (!hasPreconditioner()) { + if (CVodeSetPreconditioner(cvode_mem, nullptr, cvode_pre) != CVLS_SUCCESS) { + throw BoutException("CVodeSetPreconditioner failed\n"); + } + } else { output_info.write("\tUsing BBD preconditioner\n"); /// Get options @@ -414,62 +378,41 @@ int CvodeSolver::init() { const auto mukeep = (*options)["mukeep"].withDefault(n3Dvars() + n2Dvars()); const auto mlkeep = (*options)["mlkeep"].withDefault(n3Dvars() + n2Dvars()); - if (CVBBDPrecInit(cvode_mem, local_N, mudq, mldq, mukeep, mlkeep, ZERO, - cvode_bbd_rhs, nullptr)) { + if (CVBBDPrecInit(cvode_mem, local_N, mudq, mldq, mukeep, mlkeep, 0.0, + cvode_bbd_rhs, nullptr) + != CVLS_SUCCESS) { throw BoutException("CVBBDPrecInit failed\n"); } - - } else { - output_info.write("\tUsing user-supplied preconditioner\n"); - - if (CVSpilsSetPreconditioner(cvode_mem, nullptr, cvode_pre_shim)) { - throw BoutException("CVSpilsSetPreconditioner failed\n"); - } } } else { output_info.write("\tNo preconditioning\n"); - -#if SUNDIALS_VERSION_MAJOR >= 3 - if ((sun_solver = SUNLinSol_SPGMR(uvec, SUN_PREC_NONE, maxl, suncontext)) - == nullptr) { - throw BoutException("Creating SUNDIALS linear solver failed\n"); - } - if (CVSpilsSetLinearSolver(cvode_mem, sun_solver) != CV_SUCCESS) { - throw BoutException("CVSpilsSetLinearSolver failed\n"); - } -#else - if (CVSpgmr(cvode_mem, SUN_PREC_NONE, maxl) != CVSPILS_SUCCESS) { - throw BoutException("CVSpgmr failed\n"); - } -#endif } /// Set Jacobian-vector multiplication function if (use_jacobian and hasJacobian()) { output_info.write("\tUsing user-supplied Jacobian function\n"); - if (CVSpilsSetJacTimes(cvode_mem, nullptr, cvode_jac) != CV_SUCCESS) { - throw BoutException("CVSpilsSetJacTimesVecFn failed\n"); + if (CVodeSetJacTimes(cvode_mem, nullptr, cvode_jac) != CVLS_SUCCESS) { + throw BoutException("CVodeSetJacTimes failed\n"); } } else { output_info.write("\tUsing difference quotient approximation for Jacobian\n"); } - } else { - output_info.write("\tUsing Functional iteration\n"); -#if SUNDIALS_VERSION_MAJOR >= 4 - if ((nonlinear_solver = SUNNonlinSol_FixedPoint(uvec, 0, suncontext)) == nullptr) { - throw BoutException("SUNNonlinSol_FixedPoint failed\n"); - } + } - if (CVodeSetNonlinearSolver(cvode_mem, nonlinear_solver)) { - throw BoutException("CVodeSetNonlinearSolver failed\n"); - } +#if SUNDIALS_VERSION_MAJOR >= 6 + // Set the RHS function to be used in the nonlinear solver + CVodeSetNlsRhsFn(cvode_mem, cvode_nonlinear_rhs); #endif - } // Set internal tolerance factors - CVodeSetNonlinConvCoef(cvode_mem, cvode_nonlinear_convergence_coef); - CVodeSetEpsLin(cvode_mem, cvode_linear_convergence_coef); + if (CVodeSetNonlinConvCoef(cvode_mem, cvode_nonlinear_convergence_coef) != CV_SUCCESS) { + throw BoutException("CVodeSetNonlinConvCoef failed\n"); + } + + if (CVodeSetEpsLin(cvode_mem, cvode_linear_convergence_coef) != CV_SUCCESS) { + throw BoutException("CVodeSetEpsLin failed\n"); + } cvode_initialised = true; @@ -484,7 +427,7 @@ CvodeSolver::create_constraints(const std::vector>& fields) { constraints.reserve(fields.size()); std::transform(begin(fields), end(fields), std::back_inserter(constraints), [](const VarStr& f) { - auto f_options = Options::root()[f.name]; + auto& f_options = Options::root()[f.name]; const auto value = f_options["positivity_constraint"] .doc(fmt::format("Constraint to apply to {} if " @@ -543,9 +486,9 @@ int CvodeSolver::run() { nfevals = int(temp_long_int); CVodeGetNumNonlinSolvIters(cvode_mem, &temp_long_int); nniters = int(temp_long_int); - CVSpilsGetNumPrecSolves(cvode_mem, &temp_long_int); + CVodeGetNumPrecSolves(cvode_mem, &temp_long_int); npevals = int(temp_long_int); - CVSpilsGetNumLinIters(cvode_mem, &temp_long_int); + CVodeGetNumLinIters(cvode_mem, &temp_long_int); nliters = int(temp_long_int); // Last step size @@ -633,7 +576,7 @@ BoutReal CvodeSolver::run(BoutReal tout) { } // Copy variables - load_vars(NV_DATA_P(uvec)); + load_vars(N_VGetArrayPointer(uvec)); // Call rhs function to get extra variables at this time run_rhs(simtime); @@ -650,7 +593,7 @@ BoutReal CvodeSolver::run(BoutReal tout) { * RHS function du = F(t, u) **************************************************************************/ -void CvodeSolver::rhs(BoutReal t, BoutReal* udata, BoutReal* dudata) { +void CvodeSolver::rhs(BoutReal t, BoutReal* udata, BoutReal* dudata, bool linear) { TRACE("Running RHS: CvodeSolver::res({})", t); // Load state from udata @@ -661,7 +604,7 @@ void CvodeSolver::rhs(BoutReal t, BoutReal* udata, BoutReal* dudata) { CVodeGetLastStep(cvode_mem, &hcur); // Call RHS function - run_rhs(t); + run_rhs(t, linear); // Save derivatives to dudata save_derivs(dudata); @@ -677,11 +620,11 @@ void CvodeSolver::pre(BoutReal t, BoutReal gamma, BoutReal delta, BoutReal* udat BoutReal tstart = bout::globals::mpi->MPI_Wtime(); - int N = NV_LOCLENGTH_P(uvec); + const auto length = N_VGetLocalLength_Parallel(uvec); if (!hasPreconditioner()) { // Identity (but should never happen) - for (int i = 0; i < N; i++) { + for (int i = 0; i < length; i++) { zvec[i] = rvec[i]; } return; @@ -730,16 +673,34 @@ void CvodeSolver::jac(BoutReal t, BoutReal* ydata, BoutReal* vdata, BoutReal* Jv * CVODE RHS functions **************************************************************************/ -static int cvode_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data) { +// NOLINTBEGIN(readability-identifier-length) +namespace { +int cvode_linear_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data) { + + BoutReal* udata = N_VGetArrayPointer(u); + BoutReal* dudata = N_VGetArrayPointer(du); + + auto* s = static_cast(user_data); + + // Calculate RHS function + try { + s->rhs(t, udata, dudata, true); + } catch (BoutRhsFail& error) { + return 1; + } + return 0; +} + +int cvode_nonlinear_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data) { - BoutReal* udata = NV_DATA_P(u); - BoutReal* dudata = NV_DATA_P(du); + BoutReal* udata = N_VGetArrayPointer(u); + BoutReal* dudata = N_VGetArrayPointer(du); auto* s = static_cast(user_data); // Calculate RHS function try { - s->rhs(t, udata, dudata); + s->rhs(t, udata, dudata, false); } catch (BoutRhsFail& error) { return 1; } @@ -747,18 +708,17 @@ static int cvode_rhs(BoutReal t, N_Vector u, N_Vector du, void* user_data) { } /// RHS function for BBD preconditioner -static int cvode_bbd_rhs(CVODEINT UNUSED(Nlocal), BoutReal t, N_Vector u, N_Vector du, - void* user_data) { - return cvode_rhs(t, u, du, user_data); +int cvode_bbd_rhs(sunindextype UNUSED(Nlocal), BoutReal t, N_Vector u, N_Vector du, + void* user_data) { + return cvode_linear_rhs(t, u, du, user_data); } /// Preconditioner function -static int cvode_pre(BoutReal t, N_Vector yy, N_Vector UNUSED(yp), N_Vector rvec, - N_Vector zvec, BoutReal gamma, BoutReal delta, int UNUSED(lr), - void* user_data) { - BoutReal* udata = NV_DATA_P(yy); - BoutReal* rdata = NV_DATA_P(rvec); - BoutReal* zdata = NV_DATA_P(zvec); +int cvode_pre(BoutReal t, N_Vector yy, N_Vector UNUSED(yp), N_Vector rvec, N_Vector zvec, + BoutReal gamma, BoutReal delta, int UNUSED(lr), void* user_data) { + BoutReal* udata = N_VGetArrayPointer(yy); + BoutReal* rdata = N_VGetArrayPointer(rvec); + BoutReal* zdata = N_VGetArrayPointer(zvec); auto* s = static_cast(user_data); @@ -769,11 +729,11 @@ static int cvode_pre(BoutReal t, N_Vector yy, N_Vector UNUSED(yp), N_Vector rvec } /// Jacobian-vector multiplication function -static int cvode_jac(N_Vector v, N_Vector Jv, realtype t, N_Vector y, N_Vector UNUSED(fy), - void* user_data, N_Vector UNUSED(tmp)) { - BoutReal* ydata = NV_DATA_P(y); ///< System state - BoutReal* vdata = NV_DATA_P(v); ///< Input vector - BoutReal* Jvdata = NV_DATA_P(Jv); ///< Jacobian*vector output +int cvode_jac(N_Vector v, N_Vector Jv, BoutReal t, N_Vector y, N_Vector UNUSED(fy), + void* user_data, N_Vector UNUSED(tmp)) { + BoutReal* ydata = N_VGetArrayPointer(y); ///< System state + BoutReal* vdata = N_VGetArrayPointer(v); ///< Input vector + BoutReal* Jvdata = N_VGetArrayPointer(Jv); ///< Jacobian*vector output auto* s = static_cast(user_data); @@ -781,6 +741,8 @@ static int cvode_jac(N_Vector v, N_Vector Jv, realtype t, N_Vector y, N_Vector U return 0; } +} // namespace +// NOLINTEND(readability-identifier-length) /************************************************************************** * CVODE vector option functions @@ -828,9 +790,9 @@ void CvodeSolver::loop_vector_option_values_op(Ind2D UNUSED(i2d), BoutReal* opti void CvodeSolver::resetInternalFields() { TRACE("CvodeSolver::resetInternalFields"); - save_vars(NV_DATA_P(uvec)); + save_vars(N_VGetArrayPointer(uvec)); - if (CVodeReInit(cvode_mem, simtime, uvec) < 0) { + if (CVodeReInit(cvode_mem, simtime, uvec) != CV_SUCCESS) { throw BoutException("CVodeReInit failed\n"); } } diff --git a/src/solver/impls/cvode/cvode.hxx b/src/solver/impls/cvode/cvode.hxx index fa8b972bca..d44fcf2335 100644 --- a/src/solver/impls/cvode/cvode.hxx +++ b/src/solver/impls/cvode/cvode.hxx @@ -25,8 +25,8 @@ * **************************************************************************/ -#ifndef __SUNDIAL_SOLVER_H__ -#define __SUNDIAL_SOLVER_H__ +#ifndef BOUT_SUNDIAL_SOLVER_H +#define BOUT_SUNDIAL_SOLVER_H #include "bout/build_config.hxx" #include "bout/solver.hxx" @@ -68,8 +68,8 @@ public: void resetInternalFields() override; - // These functions used internally (but need to be public) - void rhs(BoutReal t, BoutReal* udata, BoutReal* dudata); + // These functions are used internally (but need to be public) + void rhs(BoutReal t, BoutReal* udata, BoutReal* dudata, bool linear); void pre(BoutReal t, BoutReal gamma, BoutReal delta, BoutReal* udata, BoutReal* rvec, BoutReal* zvec); void jac(BoutReal t, BoutReal* ydata, BoutReal* vdata, BoutReal* Jvdata); @@ -138,7 +138,7 @@ private: int nonlin_fails{0}; int stab_lims{0}; - bool cvode_initialised = false; + bool cvode_initialised{false}; void set_vector_option_values(BoutReal* option_data, std::vector& f2dtols, std::vector& f3dtols); @@ -157,4 +157,4 @@ private: }; #endif // BOUT_HAS_CVODE -#endif // __SUNDIAL_SOLVER_H__ +#endif // BOUT_SUNDIAL_SOLVER_H diff --git a/src/solver/impls/cvode/makefile b/src/solver/impls/cvode/makefile deleted file mode 100644 index 7c12eb1e64..0000000000 --- a/src/solver/impls/cvode/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = cvode.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/euler/euler.cxx b/src/solver/impls/euler/euler.cxx index 7bffcdeb15..3976f4402c 100644 --- a/src/solver/impls/euler/euler.cxx +++ b/src/solver/impls/euler/euler.cxx @@ -144,7 +144,7 @@ void EulerSolver::take_step(BoutReal curtime, BoutReal dt, Array& star run_rhs(curtime); save_derivs(std::begin(result)); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { result[i] = start[i] + dt * result[i]; } diff --git a/src/solver/impls/euler/euler.hxx b/src/solver/impls/euler/euler.hxx index bfa0be9bb3..0ee81a3d33 100644 --- a/src/solver/impls/euler/euler.hxx +++ b/src/solver/impls/euler/euler.hxx @@ -27,8 +27,8 @@ class EulerSolver; -#ifndef __EULER_SOLVER_H__ -#define __EULER_SOLVER_H__ +#ifndef BOUT_EULER_SOLVER_H +#define BOUT_EULER_SOLVER_H #include "mpi.h" @@ -66,4 +66,4 @@ private: Array& result); }; -#endif // __KARNIADAKIS_SOLVER_H__ +#endif // BOUT_KARNIADAKIS_SOLVER_H diff --git a/src/solver/impls/euler/makefile b/src/solver/impls/euler/makefile deleted file mode 100644 index 77576b9250..0000000000 --- a/src/solver/impls/euler/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = euler.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/ida/ida.cxx b/src/solver/impls/ida/ida.cxx index b008ebf903..cfc978f755 100644 --- a/src/solver/impls/ida/ida.cxx +++ b/src/solver/impls/ida/ida.cxx @@ -40,53 +40,23 @@ #include "bout/unused.hxx" #include - -#if SUNDIALS_VERSION_MAJOR >= 3 -#include -#include -#else -#include -#endif - #include #include #include +#include #include -#define ZERO RCONST(0.) -#define ONE RCONST(1.0) - -#ifndef IDAINT -#if SUNDIALS_VERSION_MAJOR < 3 -using IDAINT = bout::utils::function_traits::arg_t<0>; -#else -using IDAINT = sunindextype; -#endif -#endif - -static int idares(BoutReal t, N_Vector u, N_Vector du, N_Vector rr, void* user_data); -static int ida_bbd_res(IDAINT Nlocal, BoutReal t, N_Vector u, N_Vector du, N_Vector rr, - void* user_data); +// NOLINTBEGIN(readability-identifier-length) +namespace { +int idares(BoutReal t, N_Vector u, N_Vector du, N_Vector rr, void* user_data); +int ida_bbd_res(sunindextype Nlocal, BoutReal t, N_Vector u, N_Vector du, N_Vector rr, + void* user_data); -static int ida_pre(BoutReal t, N_Vector yy, N_Vector yp, N_Vector rr, N_Vector rvec, - N_Vector zvec, BoutReal cj, BoutReal delta, void* user_data); - -#if SUNDIALS_VERSION_MAJOR < 3 -// Shim for earlier versions -inline static int ida_pre_shim(BoutReal t, N_Vector yy, N_Vector yp, N_Vector rr, - N_Vector rvec, N_Vector zvec, BoutReal cj, BoutReal delta, - void* user_data, N_Vector UNUSED(tmp)) { - return ida_pre(t, yy, yp, rr, rvec, zvec, cj, delta, user_data); -} -#else -// Alias for newer versions -constexpr auto& ida_pre_shim = ida_pre; -#endif - -#if SUNDIALS_VERSION_MAJOR < 6 -void* IDACreate(MAYBE_UNUSED(SUNContext)) { return IDACreate(); } -#endif +int ida_pre(BoutReal t, N_Vector yy, N_Vector yp, N_Vector rr, N_Vector rvec, + N_Vector zvec, BoutReal cj, BoutReal delta, void* user_data); +} // namespace +// NOLINTEND(readability-identifier-length) IdaSolver::IdaSolver(Options* opts) : Solver(opts), @@ -101,15 +71,15 @@ IdaSolver::IdaSolver(Options* opts) correct_start((*options)["correct_start"] .doc("Correct the initial values") .withDefault(true)), - suncontext(static_cast(&BoutComm::get())) { + suncontext(createSUNContext(BoutComm::get())) { has_constraints = true; // This solver has constraints } IdaSolver::~IdaSolver() { if (initialised) { - N_VDestroy_Parallel(uvec); - N_VDestroy_Parallel(duvec); - N_VDestroy_Parallel(id); + N_VDestroy(uvec); + N_VDestroy(duvec); + N_VDestroy(id); IDAFree(&idamem); SUNLinSolFree(sun_solver); } @@ -144,69 +114,75 @@ int IdaSolver::init() { neq, local_N); // Allocate memory - if ((uvec = N_VNew_Parallel(BoutComm::get(), local_N, neq, suncontext)) == nullptr) { + uvec = callWithSUNContext(N_VNew_Parallel, suncontext, BoutComm::get(), local_N, neq); + if (uvec == nullptr) { throw BoutException("SUNDIALS memory allocation failed\n"); } - if ((duvec = N_VNew_Parallel(BoutComm::get(), local_N, neq, suncontext)) == nullptr) { + duvec = N_VClone(uvec); + if (duvec == nullptr) { throw BoutException("SUNDIALS memory allocation failed\n"); } - if ((id = N_VNew_Parallel(BoutComm::get(), local_N, neq, suncontext)) == nullptr) { + id = N_VClone(uvec); + if (id == nullptr) { throw BoutException("SUNDIALS memory allocation failed\n"); } // Put the variables into uvec - save_vars(NV_DATA_P(uvec)); + save_vars(N_VGetArrayPointer(uvec)); // Get the starting time derivative run_rhs(simtime); // Put the time-derivatives into duvec - save_derivs(NV_DATA_P(duvec)); + save_derivs(N_VGetArrayPointer(duvec)); // Set the equation type in id(Differential or Algebraic. This is optional) - set_id(NV_DATA_P(id)); + set_id(N_VGetArrayPointer(id)); // Call IDACreate to initialise - if ((idamem = IDACreate(suncontext)) == nullptr) { + idamem = callWithSUNContext(IDACreate, suncontext); + if (idamem == nullptr) { throw BoutException("IDACreate failed\n"); } // For callbacks, need pointer to solver object - if (IDASetUserData(idamem, this) < 0) { + if (IDASetUserData(idamem, this) != IDA_SUCCESS) { throw BoutException("IDASetUserData failed\n"); } - if (IDASetId(idamem, id) < 0) { + if (IDASetId(idamem, id) != IDA_SUCCESS) { throw BoutException("IDASetID failed\n"); } - if (IDAInit(idamem, idares, simtime, uvec, duvec) < 0) { + if (IDAInit(idamem, idares, simtime, uvec, duvec) != IDA_SUCCESS) { throw BoutException("IDAInit failed\n"); } - if (IDASStolerances(idamem, reltol, abstol) < 0) { + if (IDASStolerances(idamem, reltol, abstol) != IDA_SUCCESS) { throw BoutException("IDASStolerances failed\n"); } - IDASetMaxNumSteps(idamem, mxsteps); + if (IDASetMaxNumSteps(idamem, mxsteps) != IDA_SUCCESS) { + throw BoutException("IDASetMaxNumSteps failed\n"); + } // Call IDASpgmr to specify the IDA linear solver IDASPGMR const auto maxl = (*options)["maxl"].withDefault(6 * n3d); -#if SUNDIALS_VERSION_MAJOR >= 3 - if ((sun_solver = SUNLinSol_SPGMR(uvec, SUN_PREC_NONE, maxl, suncontext)) == nullptr) { + sun_solver = callWithSUNContext(SUNLinSol_SPGMR, suncontext, uvec, SUN_PREC_NONE, maxl); + if (sun_solver == nullptr) { throw BoutException("Creating SUNDIALS linear solver failed\n"); } - if (IDASpilsSetLinearSolver(idamem, sun_solver) != IDA_SUCCESS) { - throw BoutException("IDASpilsSetLinearSolver failed\n"); + if (IDASetLinearSolver(idamem, sun_solver, nullptr) != IDALS_SUCCESS) { + throw BoutException("IDASetLinearSolver failed\n"); } -#else - if (IDASpgmr(idamem, maxl)) { - throw BoutException("IDASpgmr failed\n"); - } -#endif if (use_precon) { - if (!hasPreconditioner()) { + if (hasPreconditioner()) { + output.write("\tUsing user-supplied preconditioner\n"); + if (IDASetPreconditioner(idamem, nullptr, ida_pre) != IDALS_SUCCESS) { + throw BoutException("IDASetPreconditioner failed\n"); + } + } else { output.write("\tUsing BBD preconditioner\n"); /// Get options // Compute band_width_default from actually added fields, to allow for multiple Mesh @@ -225,21 +201,17 @@ int IdaSolver::init() { const auto mldq = (*options)["mldq"].withDefault(band_width_default); const auto mukeep = (*options)["mukeep"].withDefault(n3d); const auto mlkeep = (*options)["mlkeep"].withDefault(n3d); - if (IDABBDPrecInit(idamem, local_N, mudq, mldq, mukeep, mlkeep, ZERO, ida_bbd_res, - nullptr)) { + if (IDABBDPrecInit(idamem, local_N, mudq, mldq, mukeep, mlkeep, 0.0, ida_bbd_res, + nullptr) + != IDALS_SUCCESS) { throw BoutException("IDABBDPrecInit failed\n"); } - } else { - output.write("\tUsing user-supplied preconditioner\n"); - if (IDASpilsSetPreconditioner(idamem, nullptr, ida_pre_shim)) { - throw BoutException("IDASpilsSetPreconditioner failed\n"); - } } } // Call IDACalcIC (with default options) to correct the initial values if (correct_start) { - if (IDACalcIC(idamem, IDA_YA_YDP_INIT, 1e-6)) { + if (IDACalcIC(idamem, IDA_YA_YDP_INIT, 1e-6) != IDA_SUCCESS) { throw BoutException("IDACalcIC failed\n"); } } @@ -291,7 +263,7 @@ BoutReal IdaSolver::run(BoutReal tout) { const int flag = IDASolve(idamem, tout, &simtime, uvec, duvec, IDA_NORMAL); // Copy variables - load_vars(NV_DATA_P(uvec)); + load_vars(N_VGetArrayPointer(uvec)); // Call rhs function to get extra variables at this time run_rhs(simtime); @@ -322,9 +294,9 @@ void IdaSolver::res(BoutReal t, BoutReal* udata, BoutReal* dudata, BoutReal* rda save_derivs(rdata); // If a differential equation, subtract dudata - const int N = NV_LOCLENGTH_P(id); - const BoutReal* idd = NV_DATA_P(id); - for (int i = 0; i < N; i++) { + const auto length = N_VGetLocalLength_Parallel(id); + const BoutReal* idd = N_VGetArrayPointer(id); + for (int i = 0; i < length; i++) { if (idd[i] > 0.5) { // 1 -> differential, 0 -> algebraic rdata[i] -= dudata[i]; } @@ -343,8 +315,8 @@ void IdaSolver::pre(BoutReal t, BoutReal cj, BoutReal delta, BoutReal* udata, if (!hasPreconditioner()) { // Identity (but should never happen) - const int N = NV_LOCLENGTH_P(id); - std::copy(rvec, rvec + N, zvec); + const auto length = N_VGetLocalLength_Parallel(id); + std::copy(rvec, rvec + length, zvec); return; } @@ -367,10 +339,12 @@ void IdaSolver::pre(BoutReal t, BoutReal cj, BoutReal delta, BoutReal* udata, * IDA res function **************************************************************************/ -static int idares(BoutReal t, N_Vector u, N_Vector du, N_Vector rr, void* user_data) { - BoutReal* udata = NV_DATA_P(u); - BoutReal* dudata = NV_DATA_P(du); - BoutReal* rdata = NV_DATA_P(rr); +// NOLINTBEGIN(readability-identifier-length) +namespace { +int idares(BoutReal t, N_Vector u, N_Vector du, N_Vector rr, void* user_data) { + BoutReal* udata = N_VGetArrayPointer(u); + BoutReal* dudata = N_VGetArrayPointer(du); + BoutReal* rdata = N_VGetArrayPointer(rr); auto* s = static_cast(user_data); @@ -381,18 +355,17 @@ static int idares(BoutReal t, N_Vector u, N_Vector du, N_Vector rr, void* user_d } /// Residual function for BBD preconditioner -static int ida_bbd_res(IDAINT UNUSED(Nlocal), BoutReal t, N_Vector u, N_Vector du, - N_Vector rr, void* user_data) { +int ida_bbd_res(sunindextype UNUSED(Nlocal), BoutReal t, N_Vector u, N_Vector du, + N_Vector rr, void* user_data) { return idares(t, u, du, rr, user_data); } // Preconditioner function -static int ida_pre(BoutReal t, N_Vector yy, N_Vector UNUSED(yp), N_Vector UNUSED(rr), - N_Vector rvec, N_Vector zvec, BoutReal cj, BoutReal delta, - void* user_data) { - BoutReal* udata = NV_DATA_P(yy); - BoutReal* rdata = NV_DATA_P(rvec); - BoutReal* zdata = NV_DATA_P(zvec); +int ida_pre(BoutReal t, N_Vector yy, N_Vector UNUSED(yp), N_Vector UNUSED(rr), + N_Vector rvec, N_Vector zvec, BoutReal cj, BoutReal delta, void* user_data) { + BoutReal* udata = N_VGetArrayPointer(yy); + BoutReal* rdata = N_VGetArrayPointer(rvec); + BoutReal* zdata = N_VGetArrayPointer(zvec); auto* s = static_cast(user_data); @@ -401,5 +374,7 @@ static int ida_pre(BoutReal t, N_Vector yy, N_Vector UNUSED(yp), N_Vector UNUSED return 0; } +} // namespace +// NOLINTEND(readability-identifier-length) #endif diff --git a/src/solver/impls/ida/ida.hxx b/src/solver/impls/ida/ida.hxx index 83ee4d83e6..b00054d157 100644 --- a/src/solver/impls/ida/ida.hxx +++ b/src/solver/impls/ida/ida.hxx @@ -27,8 +27,8 @@ * **************************************************************************/ -#ifndef __IDA_SOLVER_H__ -#define __IDA_SOLVER_H__ +#ifndef BOUT_IDA_SOLVER_H +#define BOUT_IDA_SOLVER_H #include "bout/build_config.hxx" #include "bout/solver.hxx" @@ -97,4 +97,4 @@ private: }; #endif // BOUT_HAS_IDA -#endif // __IDA_SOLVER_H__ +#endif // BOUT_IDA_SOLVER_H diff --git a/src/solver/impls/ida/makefile b/src/solver/impls/ida/makefile deleted file mode 100644 index 87d2322a11..0000000000 --- a/src/solver/impls/ida/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = ida.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/imex-bdf2/imex-bdf2.cxx b/src/solver/impls/imex-bdf2/imex-bdf2.cxx index adafbb71c5..da62e9b8bb 100644 --- a/src/solver/impls/imex-bdf2/imex-bdf2.cxx +++ b/src/solver/impls/imex-bdf2/imex-bdf2.cxx @@ -18,9 +18,6 @@ #include "petscmat.h" #include "petscsnes.h" -// Redundent definition because < C++17 -constexpr int IMEXBDF2::MAX_SUPPORTED_ORDER; - IMEXBDF2::IMEXBDF2(Options* opt) : Solver(opt), maxOrder((*options)["maxOrder"] .doc("Maximum order of the scheme (1/2/3)") diff --git a/src/solver/impls/imex-bdf2/imex-bdf2.hxx b/src/solver/impls/imex-bdf2/imex-bdf2.hxx index 4126c48265..f0e1b2faee 100644 --- a/src/solver/impls/imex-bdf2/imex-bdf2.hxx +++ b/src/solver/impls/imex-bdf2/imex-bdf2.hxx @@ -32,8 +32,8 @@ * **************************************************************************/ -#ifndef __IMEXBDF2_SOLVER_H__ -#define __IMEXBDF2_SOLVER_H__ +#ifndef BOUT_IMEXBDF2_SOLVER_H +#define BOUT_IMEXBDF2_SOLVER_H #include "bout/build_config.hxx" #include "bout/solver.hxx" @@ -221,6 +221,6 @@ private: void saveDerivs(BoutReal* u); }; -#endif // __IMEXBDF2_SOLVER_H__ +#endif // BOUT_IMEXBDF2_SOLVER_H #endif // BOUT_HAS_PETSC diff --git a/src/solver/impls/imex-bdf2/makefile b/src/solver/impls/imex-bdf2/makefile deleted file mode 100644 index 845ade8ae4..0000000000 --- a/src/solver/impls/imex-bdf2/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = imex-bdf2.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/makefile b/src/solver/impls/makefile deleted file mode 100644 index 25729c1641..0000000000 --- a/src/solver/impls/makefile +++ /dev/null @@ -1,13 +0,0 @@ - -BOUT_TOP = ../../.. - -DIRS = arkode \ - pvode cvode ida \ - petsc \ - snes imex-bdf2 \ - power slepc adams_bashforth \ - rk4 euler rk3-ssp rkgeneric split-rk - -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/petsc/makefile b/src/solver/impls/petsc/makefile deleted file mode 100644 index ac2218bc76..0000000000 --- a/src/solver/impls/petsc/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = petsc.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/petsc/petsc.cxx b/src/solver/impls/petsc/petsc.cxx index 1b81ca36b6..7a2b2cf3de 100644 --- a/src/solver/impls/petsc/petsc.cxx +++ b/src/solver/impls/petsc/petsc.cxx @@ -29,7 +29,6 @@ #if BOUT_HAS_PETSC -//#include #include #include @@ -750,10 +749,10 @@ PetscErrorCode solver_rhsjacobian(TS UNUSED(ts), BoutReal UNUSED(t), Vec UNUSED( PetscFunctionReturn(0); } #else -PetscErrorCode solver_rhsjacobian(MAYBE_UNUSED(TS ts), MAYBE_UNUSED(BoutReal t), - MAYBE_UNUSED(Vec globalin), Mat* J, Mat* Jpre, - MAYBE_UNUSED(MatStructure* str), - MAYBE_UNUSED(void* f_data)) { +PetscErrorCode solver_rhsjacobian([[maybe_unused]] TS ts, [[maybe_unused]] BoutReal t, + [[maybe_unused]] Vec globalin, Mat* J, Mat* Jpre, + [[maybe_unused]] MatStructure* str, + [[maybe_unused]] void* f_data) { PetscErrorCode ierr; PetscFunctionBegin; @@ -798,8 +797,9 @@ PetscErrorCode solver_ijacobian(TS ts, BoutReal t, Vec globalin, Vec UNUSED(glob } #else PetscErrorCode solver_ijacobian(TS ts, BoutReal t, Vec globalin, - MAYBE_UNUSED(Vec globalindot), MAYBE_UNUSED(PetscReal a), - Mat* J, Mat* Jpre, MatStructure* str, void* f_data) { + [[maybe_unused]] Vec globalindot, + [[maybe_unused]] PetscReal a, Mat* J, Mat* Jpre, + MatStructure* str, void* f_data) { PetscErrorCode ierr; PetscFunctionBegin; diff --git a/src/solver/impls/petsc/petsc.hxx b/src/solver/impls/petsc/petsc.hxx index 349f40bad8..7239126abb 100644 --- a/src/solver/impls/petsc/petsc.hxx +++ b/src/solver/impls/petsc/petsc.hxx @@ -24,8 +24,8 @@ * **************************************************************************/ -#ifndef __PETSC_SOLVER_H__ -#define __PETSC_SOLVER_H__ +#ifndef BOUT_PETSC_SOLVER_H +#define BOUT_PETSC_SOLVER_H #include "bout/build_config.hxx" #include "bout/solver.hxx" @@ -149,4 +149,4 @@ private: #endif // BOUT_HAS_PETSC -#endif // __PETSC_SOLVER_H__ +#endif // BOUT_PETSC_SOLVER_H diff --git a/src/solver/impls/power/makefile b/src/solver/impls/power/makefile deleted file mode 100644 index b2fef299d8..0000000000 --- a/src/solver/impls/power/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = power.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/power/power.hxx b/src/solver/impls/power/power.hxx index 757befeec5..6f56c20f43 100644 --- a/src/solver/impls/power/power.hxx +++ b/src/solver/impls/power/power.hxx @@ -26,8 +26,8 @@ class PowerSolver; -#ifndef __POWER_SOLVER_H__ -#define __POWER_SOLVER_H__ +#ifndef BOUT_POWER_SOLVER_H +#define BOUT_POWER_SOLVER_H #include #include @@ -60,4 +60,4 @@ private: void divide(Array& in, BoutReal value); }; -#endif // __KARNIADAKIS_SOLVER_H__ +#endif // BOUT_KARNIADAKIS_SOLVER_H diff --git a/src/solver/impls/pvode/makefile b/src/solver/impls/pvode/makefile deleted file mode 100644 index 72d132b150..0000000000 --- a/src/solver/impls/pvode/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = pvode.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/pvode/pvode.hxx b/src/solver/impls/pvode/pvode.hxx index 2ff02c22bf..d29135d02e 100644 --- a/src/solver/impls/pvode/pvode.hxx +++ b/src/solver/impls/pvode/pvode.hxx @@ -30,8 +30,8 @@ class PvodeSolver; -#ifndef __PVODE_SOLVER_H__ -#define __PVODE_SOLVER_H__ +#ifndef BOUT_PVODE_SOLVER_H +#define BOUT_PVODE_SOLVER_H #include #include @@ -81,6 +81,6 @@ private: bool pvode_initialised = false; }; -#endif // __PVODE_SOLVER_H__ +#endif // BOUT_PVODE_SOLVER_H #endif diff --git a/src/solver/impls/rk3-ssp/makefile b/src/solver/impls/rk3-ssp/makefile deleted file mode 100644 index 8cae9d3c25..0000000000 --- a/src/solver/impls/rk3-ssp/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = rk3-ssp.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/rk3-ssp/rk3-ssp.cxx b/src/solver/impls/rk3-ssp/rk3-ssp.cxx index 27979bc435..e13d996c00 100644 --- a/src/solver/impls/rk3-ssp/rk3-ssp.cxx +++ b/src/solver/impls/rk3-ssp/rk3-ssp.cxx @@ -108,7 +108,7 @@ void RK3SSP::take_step(BoutReal curtime, BoutReal dt, Array& start, run_rhs(curtime); save_derivs(std::begin(L)); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { u1[i] = start[i] + dt * L[i]; } @@ -117,7 +117,7 @@ void RK3SSP::take_step(BoutReal curtime, BoutReal dt, Array& start, run_rhs(curtime + dt); save_derivs(std::begin(L)); - BOUT_OMP(parallel for ) + BOUT_OMP_PERF(parallel for ) for (int i = 0; i < nlocal; i++) { u2[i] = 0.75 * start[i] + 0.25 * u1[i] + 0.25 * dt * L[i]; } @@ -126,7 +126,7 @@ void RK3SSP::take_step(BoutReal curtime, BoutReal dt, Array& start, run_rhs(curtime + 0.5 * dt); save_derivs(std::begin(L)); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { result[i] = (1. / 3) * start[i] + (2. / 3.) * (u2[i] + dt * L[i]); } diff --git a/src/solver/impls/rk3-ssp/rk3-ssp.hxx b/src/solver/impls/rk3-ssp/rk3-ssp.hxx index 4080b17bb5..3682d5cbde 100644 --- a/src/solver/impls/rk3-ssp/rk3-ssp.hxx +++ b/src/solver/impls/rk3-ssp/rk3-ssp.hxx @@ -33,8 +33,8 @@ class RK3SSP; -#ifndef __RK3SSP_SOLVER_H__ -#define __RK3SSP_SOLVER_H__ +#ifndef BOUT_RK3SSP_SOLVER_H +#define BOUT_RK3SSP_SOLVER_H #include "mpi.h" @@ -72,4 +72,4 @@ private: Array u1, u2, u3, L; //< Time-stepping arrays }; -#endif // __RK4_SOLVER_H__ +#endif // BOUT_RK3SSP_SOLVER_H diff --git a/src/solver/impls/rk4/makefile b/src/solver/impls/rk4/makefile deleted file mode 100644 index 04fad4a71f..0000000000 --- a/src/solver/impls/rk4/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = rk4.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/rk4/rk4.cxx b/src/solver/impls/rk4/rk4.cxx index 47bef38f9c..0e7a942a45 100644 --- a/src/solver/impls/rk4/rk4.cxx +++ b/src/solver/impls/rk4/rk4.cxx @@ -105,7 +105,7 @@ int RK4Solver::run() { // Check accuracy BoutReal local_err = 0.; - BOUT_OMP(parallel for reduction(+: local_err) ) + BOUT_OMP_PERF(parallel for reduction(+: local_err) ) for (int i = 0; i < nlocal; i++) { local_err += fabs(f2[i] - f1[i]) / (fabs(f1[i]) + fabs(f2[i]) + atol); } @@ -182,7 +182,7 @@ void RK4Solver::take_step(BoutReal curtime, BoutReal dt, Array& start, run_rhs(curtime); save_derivs(std::begin(k1)); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { k5[i] = start[i] + 0.5 * dt * k1[i]; } @@ -191,7 +191,7 @@ void RK4Solver::take_step(BoutReal curtime, BoutReal dt, Array& start, run_rhs(curtime + 0.5 * dt); save_derivs(std::begin(k2)); - BOUT_OMP(parallel for ) + BOUT_OMP_PERF(parallel for ) for (int i = 0; i < nlocal; i++) { k5[i] = start[i] + 0.5 * dt * k2[i]; } @@ -200,7 +200,7 @@ void RK4Solver::take_step(BoutReal curtime, BoutReal dt, Array& start, run_rhs(curtime + 0.5 * dt); save_derivs(std::begin(k3)); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { k5[i] = start[i] + dt * k3[i]; } @@ -209,7 +209,7 @@ void RK4Solver::take_step(BoutReal curtime, BoutReal dt, Array& start, run_rhs(curtime + dt); save_derivs(std::begin(k4)); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { result[i] = start[i] + (1. / 6.) * dt * (k1[i] + 2. * k2[i] + 2. * k3[i] + k4[i]); } diff --git a/src/solver/impls/rk4/rk4.hxx b/src/solver/impls/rk4/rk4.hxx index 5838b24e8e..7ec7e6dd45 100644 --- a/src/solver/impls/rk4/rk4.hxx +++ b/src/solver/impls/rk4/rk4.hxx @@ -27,8 +27,8 @@ class RK4Solver; -#ifndef __RK4_SOLVER_H__ -#define __RK4_SOLVER_H__ +#ifndef BOUT_RK4_SOLVER_H +#define BOUT_RK4_SOLVER_H #include "mpi.h" @@ -68,4 +68,4 @@ private: Array k1, k2, k3, k4, k5; //< Time-stepping arrays }; -#endif // __RK4_SOLVER_H__ +#endif // BOUT_RK4_SOLVER_H diff --git a/src/solver/impls/rkgeneric/impls/cashkarp/cashkarp.hxx b/src/solver/impls/rkgeneric/impls/cashkarp/cashkarp.hxx index 32072f1fc7..76042174f9 100644 --- a/src/solver/impls/rkgeneric/impls/cashkarp/cashkarp.hxx +++ b/src/solver/impls/rkgeneric/impls/cashkarp/cashkarp.hxx @@ -1,8 +1,8 @@ class CASHKARPScheme; -#ifndef __CASHKARP_SCHEME_H__ -#define __CASHKARP_SCHEME_H__ +#ifndef BOUT_CASHKARP_SCHEME_H +#define BOUT_CASHKARP_SCHEME_H #include #include @@ -16,4 +16,4 @@ namespace { RegisterRKScheme registerrkschemecashkarp(RKSCHEME_CASHKARP); } -#endif // __CASHKARP_SCHEME_H__ +#endif // BOUT_CASHKARP_SCHEME_H diff --git a/src/solver/impls/rkgeneric/impls/cashkarp/makefile b/src/solver/impls/rkgeneric/impls/cashkarp/makefile deleted file mode 100644 index 92a372d753..0000000000 --- a/src/solver/impls/rkgeneric/impls/cashkarp/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../../.. - -SOURCEC = cashkarp.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/rkgeneric/impls/makefile b/src/solver/impls/rkgeneric/impls/makefile deleted file mode 100644 index 62e5253110..0000000000 --- a/src/solver/impls/rkgeneric/impls/makefile +++ /dev/null @@ -1,7 +0,0 @@ - -BOUT_TOP = ../../../../.. - -DIRS = rkf45 cashkarp rk4simple rkf34 -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/rkgeneric/impls/rk4simple/makefile b/src/solver/impls/rkgeneric/impls/rk4simple/makefile deleted file mode 100644 index f0cf42ae7a..0000000000 --- a/src/solver/impls/rkgeneric/impls/rk4simple/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../../.. - -SOURCEC = rk4simple.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/rkgeneric/impls/rk4simple/rk4simple.hxx b/src/solver/impls/rkgeneric/impls/rk4simple/rk4simple.hxx index 126fa0912c..9fc0fc0604 100644 --- a/src/solver/impls/rkgeneric/impls/rk4simple/rk4simple.hxx +++ b/src/solver/impls/rkgeneric/impls/rk4simple/rk4simple.hxx @@ -1,8 +1,8 @@ class RK4SIMPLEScheme; -#ifndef __RK4SIMPLE_SCHEME_H__ -#define __RK4SIMPLE_SCHEME_H__ +#ifndef BOUT_RK4SIMPLE_SCHEME_H +#define BOUT_RK4SIMPLE_SCHEME_H #include #include @@ -19,4 +19,4 @@ namespace { RegisterRKScheme registerrkscheme4simple(RKSCHEME_RK4); } -#endif // __RK4SIMPLE_SCHEME_H__ +#endif // BOUT_RK4SIMPLE_SCHEME_H diff --git a/src/solver/impls/rkgeneric/impls/rkf34/makefile b/src/solver/impls/rkgeneric/impls/rkf34/makefile deleted file mode 100644 index d7c13604e2..0000000000 --- a/src/solver/impls/rkgeneric/impls/rkf34/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../../.. - -SOURCEC = rkf34.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/rkgeneric/impls/rkf34/rkf34.hxx b/src/solver/impls/rkgeneric/impls/rkf34/rkf34.hxx index 9de022b865..6840c4f5b4 100644 --- a/src/solver/impls/rkgeneric/impls/rkf34/rkf34.hxx +++ b/src/solver/impls/rkgeneric/impls/rkf34/rkf34.hxx @@ -1,8 +1,8 @@ class RKF34Scheme; -#ifndef __RKF34_SCHEME_H__ -#define __RKF34_SCHEME_H__ +#ifndef BOUT_RKF34_SCHEME_H +#define BOUT_RKF34_SCHEME_H #include #include @@ -16,4 +16,4 @@ namespace { RegisterRKScheme registerrkschemef34(RKSCHEME_RKF34); } -#endif // __RKF34_SCHEME_H__ +#endif // BOUT_RKF34_SCHEME_H diff --git a/src/solver/impls/rkgeneric/impls/rkf45/makefile b/src/solver/impls/rkgeneric/impls/rkf45/makefile deleted file mode 100644 index 6f5095b504..0000000000 --- a/src/solver/impls/rkgeneric/impls/rkf45/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../../../.. - -SOURCEC = rkf45.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/rkgeneric/impls/rkf45/rkf45.hxx b/src/solver/impls/rkgeneric/impls/rkf45/rkf45.hxx index ea752877e0..70150a2a40 100644 --- a/src/solver/impls/rkgeneric/impls/rkf45/rkf45.hxx +++ b/src/solver/impls/rkgeneric/impls/rkf45/rkf45.hxx @@ -1,8 +1,8 @@ class RKF45Scheme; -#ifndef __RKF45_SCHEME_H__ -#define __RKF45_SCHEME_H__ +#ifndef BOUT_RKF45_SCHEME_H +#define BOUT_RKF45_SCHEME_H #include #include @@ -16,4 +16,4 @@ namespace { RegisterRKScheme registerrkschemef45(RKSCHEME_RKF45); } -#endif // __RKF45_SCHEME_H__ +#endif // BOUT_RKF45_SCHEME_H diff --git a/src/solver/impls/rkgeneric/makefile b/src/solver/impls/rkgeneric/makefile deleted file mode 100644 index 02e443a7d9..0000000000 --- a/src/solver/impls/rkgeneric/makefile +++ /dev/null @@ -1,9 +0,0 @@ - -BOUT_TOP = ../../../.. - -DIRS = impls -SOURCEC = rkgeneric.cxx rkscheme.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/rkgeneric/rkgeneric.cxx b/src/solver/impls/rkgeneric/rkgeneric.cxx index 8f5e95f0be..1c332d26de 100644 --- a/src/solver/impls/rkgeneric/rkgeneric.cxx +++ b/src/solver/impls/rkgeneric/rkgeneric.cxx @@ -75,7 +75,7 @@ int RKGenericSolver::init() { void RKGenericSolver::resetInternalFields() { //Zero out history - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { tmpState[i] = 0; f2[i] = 0; diff --git a/src/solver/impls/rkgeneric/rkgeneric.hxx b/src/solver/impls/rkgeneric/rkgeneric.hxx index a18678e724..9df9a4a396 100644 --- a/src/solver/impls/rkgeneric/rkgeneric.hxx +++ b/src/solver/impls/rkgeneric/rkgeneric.hxx @@ -25,8 +25,8 @@ class RKGenericSolver; -#ifndef __RKGENERIC_SOLVER_H__ -#define __RKGENERIC_SOLVER_H__ +#ifndef BOUT_RKGENERIC_SOLVER_H +#define BOUT_RKGENERIC_SOLVER_H #include "mpi.h" @@ -77,4 +77,4 @@ private: std::unique_ptr scheme{nullptr}; }; -#endif // __RKGENERIC_SOLVER_H__ +#endif // BOUT_RKGENERIC_SOLVER_H diff --git a/src/solver/impls/rkgeneric/rkscheme.cxx b/src/solver/impls/rkgeneric/rkscheme.cxx index 740adec909..dd4bd8e7a1 100644 --- a/src/solver/impls/rkgeneric/rkscheme.cxx +++ b/src/solver/impls/rkgeneric/rkscheme.cxx @@ -59,7 +59,7 @@ void RKScheme::setCurState(const Array& start, Array& out, const int curStage, const BoutReal dt) { //Set the initial stage - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { out[i] = start[i]; } @@ -76,7 +76,7 @@ void RKScheme::setCurState(const Array& start, Array& out, } BoutReal fac = stageCoeffs(curStage, j) * dt; - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { out[i] = out[i] + fac * steps(j, i); } @@ -147,7 +147,7 @@ BoutReal RKScheme::getErr(Array& solA, Array& solB) { // we expect slightly different round-off error each time this // is called and hence the nrhs may no longer be exactly // repeatable with this parallelisation. - BOUT_OMP(parallel for reduction(+:local_err)) + BOUT_OMP_PERF(parallel for reduction(+:local_err)) for (int i = 0; i < nlocal; i++) { local_err += std::abs(solA[i] - solB[i]) / (std::abs(solA[i]) + std::abs(solB[i]) + atol); @@ -166,7 +166,7 @@ BoutReal RKScheme::getErr(Array& solA, Array& solB) { void RKScheme::constructOutput(const Array& start, const BoutReal dt, const int index, Array& sol) { //Initialise the return data - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { sol[i] = start[i]; } @@ -177,7 +177,7 @@ void RKScheme::constructOutput(const Array& start, const BoutReal dt, continue; // Real comparison not great } BoutReal fac = dt * resultCoeffs(curStage, index); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { sol[i] = sol[i] + fac * steps(curStage, i); } @@ -188,7 +188,7 @@ void RKScheme::constructOutputs(const Array& start, const BoutReal dt, const int indexFollow, const int indexAlt, Array& solFollow, Array& solAlt) { //Initialise the return data - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { solFollow[i] = start[i]; solAlt[i] = start[i]; @@ -198,7 +198,7 @@ void RKScheme::constructOutputs(const Array& start, const BoutReal dt, for (int curStage = 0; curStage < getStageCount(); curStage++) { BoutReal facFol = dt * resultCoeffs(curStage, indexFollow); BoutReal facAlt = dt * resultCoeffs(curStage, indexAlt); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { solFollow[i] = solFollow[i] + facFol * steps(curStage, i); solAlt[i] = solAlt[i] + facAlt * steps(curStage, i); @@ -308,8 +308,3 @@ void RKScheme::zeroSteps() { } } } - -constexpr decltype(RKSchemeFactory::type_name) RKSchemeFactory::type_name; -constexpr decltype(RKSchemeFactory::section_name) RKSchemeFactory::section_name; -constexpr decltype(RKSchemeFactory::option_name) RKSchemeFactory::option_name; -constexpr decltype(RKSchemeFactory::default_type) RKSchemeFactory::default_type; diff --git a/src/solver/impls/slepc/makefile b/src/solver/impls/slepc/makefile deleted file mode 100644 index ae9b7b43e4..0000000000 --- a/src/solver/impls/slepc/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = slepc.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/slepc/slepc.cxx b/src/solver/impls/slepc/slepc.cxx index f90afe717e..8cbb002d11 100644 --- a/src/solver/impls/slepc/slepc.cxx +++ b/src/solver/impls/slepc/slepc.cxx @@ -572,7 +572,7 @@ void SlepcSolver::monitor(PetscInt its, PetscInt nconv, PetscScalar eigr[], static int nConvPrev = 0; // Disable floating-point exceptions for the duration of this function - MAYBE_UNUSED(QuietFPE quiet_fpe{}); + [[maybe_unused]] QuietFPE quiet_fpe{}; // No output until after first iteration if (its < 1) { diff --git a/src/solver/impls/slepc/slepc.hxx b/src/solver/impls/slepc/slepc.hxx index 88f35a04f9..619c873132 100644 --- a/src/solver/impls/slepc/slepc.hxx +++ b/src/solver/impls/slepc/slepc.hxx @@ -24,8 +24,8 @@ * **************************************************************************/ -#ifndef __SLEPC_SOLVER_H__ -#define __SLEPC_SOLVER_H__ +#ifndef BOUT_SLEPC_SOLVER_H +#define BOUT_SLEPC_SOLVER_H #include "bout/build_config.hxx" #include "bout/solver.hxx" @@ -234,4 +234,4 @@ private: #endif // BOUT_HAS_SLEPC -#endif // __SLEPC_SOLVER_H__ +#endif // BOUT_SLEPC_SOLVER_H diff --git a/src/solver/impls/snes/makefile b/src/solver/impls/snes/makefile deleted file mode 100644 index 8228444a5e..0000000000 --- a/src/solver/impls/snes/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = snes.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/snes/snes.hxx b/src/solver/impls/snes/snes.hxx index 2021402cd7..601eaaaa25 100644 --- a/src/solver/impls/snes/snes.hxx +++ b/src/solver/impls/snes/snes.hxx @@ -25,8 +25,8 @@ * **************************************************************************/ -#ifndef __SNES_SOLVER_H__ -#define __SNES_SOLVER_H__ +#ifndef BOUT_SNES_SOLVER_H +#define BOUT_SNES_SOLVER_H #include #include @@ -143,4 +143,4 @@ RegisterUnavailableSolver #endif // BOUT_HAS_PETSC -#endif // __SNES_SOLVER_H__ +#endif // BOUT_SNES_SOLVER_H diff --git a/src/solver/impls/split-rk/makefile b/src/solver/impls/split-rk/makefile deleted file mode 100644 index 4d8153a3b5..0000000000 --- a/src/solver/impls/split-rk/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = split-rk.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/impls/split-rk/split-rk.cxx b/src/solver/impls/split-rk/split-rk.cxx index ef53a12f2e..cd6bd1718c 100644 --- a/src/solver/impls/split-rk/split-rk.cxx +++ b/src/solver/impls/split-rk/split-rk.cxx @@ -113,7 +113,7 @@ int SplitRK::run() { // Check accuracy BoutReal local_err = 0.; - BOUT_OMP(parallel for reduction(+: local_err) ) + BOUT_OMP_PERF(parallel for reduction(+: local_err) ) for (int i = 0; i < nlocal; i++) { local_err += fabs(state2[i] - state1[i]) / (fabs(state1[i]) + fabs(state2[i]) + atol); @@ -220,7 +220,7 @@ void SplitRK::take_diffusion_step(BoutReal curtime, BoutReal dt, Array // Stage j = 1 // y_m2 = y0 + weight/3.0 * f(y0) -> u2 - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < dydt.size(); i++) { u2[i] = start[i] + (weight / 3.0) * dydt[i]; } @@ -231,7 +231,7 @@ void SplitRK::take_diffusion_step(BoutReal curtime, BoutReal dt, Array run_diffusive(curtime + (weight / 3.0) * dt); save_derivs(std::begin(u3)); // f(y_m2) -> u3 - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < u3.size(); i++) { u1[i] = 1.5 * (u2[i] + weight * u3[i]) - 0.5 * start[i] - weight * dydt[i]; } @@ -251,7 +251,7 @@ void SplitRK::take_diffusion_step(BoutReal curtime, BoutReal dt, Array run_diffusive(curtime); save_derivs(std::begin(u3)); // f(y_m1) -> u3 - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < u3.size(); i++) { // Next stage result in u3 u3[i] = mu * (u1[i] + weight * (u3[i] - a_jm1 * dydt[i])) + nu * u2[i] @@ -280,7 +280,7 @@ void SplitRK::take_advection_step(BoutReal curtime, BoutReal dt, Array run_convective(curtime); save_derivs(std::begin(dydt)); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { u1[i] = start[i] + dt * dydt[i]; } @@ -289,7 +289,7 @@ void SplitRK::take_advection_step(BoutReal curtime, BoutReal dt, Array run_convective(curtime + dt); save_derivs(std::begin(dydt)); - BOUT_OMP(parallel for ) + BOUT_OMP_PERF(parallel for ) for (int i = 0; i < nlocal; i++) { u2[i] = 0.75 * start[i] + 0.25 * u1[i] + 0.25 * dt * dydt[i]; } @@ -298,7 +298,7 @@ void SplitRK::take_advection_step(BoutReal curtime, BoutReal dt, Array run_convective(curtime + 0.5 * dt); save_derivs(std::begin(dydt)); - BOUT_OMP(parallel for) + BOUT_OMP_PERF(parallel for) for (int i = 0; i < nlocal; i++) { result[i] = (1. / 3) * start[i] + (2. / 3.) * (u2[i] + dt * dydt[i]); } diff --git a/src/solver/makefile b/src/solver/makefile deleted file mode 100644 index 7aa0327328..0000000000 --- a/src/solver/makefile +++ /dev/null @@ -1,8 +0,0 @@ -BOUT_TOP = ../.. - -DIRS = impls -SOURCEC = solver.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/solver/solver.cxx b/src/solver/solver.cxx index 9dd31f011e..8a75ff43a4 100644 --- a/src/solver/solver.cxx +++ b/src/solver/solver.cxx @@ -973,12 +973,6 @@ int Solver::call_timestep_monitors(BoutReal simtime, BoutReal lastdt) { * Useful routines (protected) **************************************************************************/ -template -int local_N_sum(int value, const Solver::VarStr& f) { - const auto boundary_size = f.evolve_bndry ? size(f.var->getRegion("RGN_BNDRY")) : 0; - return value + boundary_size + size(f.var->getRegion("RGN_NOBNDRY")); -} - int Solver::getLocalN() { // Cache the value, so this is not repeatedly called. @@ -991,8 +985,16 @@ int Solver::getLocalN() { // Must be initialised ASSERT0(initialised); - const auto local_N_2D = std::accumulate(begin(f2d), end(f2d), 0, local_N_sum); - const auto local_N_3D = std::accumulate(begin(f3d), end(f3d), 0, local_N_sum); + // Return the number of points to evolve in f, plus the accumulator value. + // If f.evolve_bndry, includes the boundary (NB: not guard!) points + auto local_N_sum = [](int value, const auto& field) -> int { + const auto boundary_size = + field.evolve_bndry ? size(field.var->getRegion("RGN_BNDRY")) : 0; + return value + boundary_size + size(field.var->getRegion("RGN_NOBNDRY")); + }; + + const auto local_N_2D = std::accumulate(begin(f2d), end(f2d), 0, local_N_sum); + const auto local_N_3D = std::accumulate(begin(f3d), end(f3d), 0, local_N_sum); const auto local_N = local_N_2D + local_N_3D; cacheLocalN = local_N; @@ -1362,6 +1364,12 @@ int Solver::run_rhs(BoutReal t, bool linear) { Timer timer("rhs"); + if (first_rhs_call) { + // Ensure that nonlinear terms are calculated on first call + linear = false; + first_rhs_call = false; + } + if (model->splitOperator()) { // Run both parts @@ -1498,7 +1506,7 @@ void Solver::post_rhs(BoutReal UNUSED(t)) { } // Make sure 3D fields are at the correct cell location, etc. - for (MAYBE_UNUSED(const auto& f) : f3d) { + for ([[maybe_unused]] const auto& f : f3d) { ASSERT1_FIELDS_COMPATIBLE(*f.var, *f.F_var); } @@ -1571,8 +1579,3 @@ void Solver::calculate_mms_error(BoutReal t) { *(f.MMS_err) = *(f.var) - solution; } } - -constexpr decltype(SolverFactory::type_name) SolverFactory::type_name; -constexpr decltype(SolverFactory::section_name) SolverFactory::section_name; -constexpr decltype(SolverFactory::option_name) SolverFactory::option_name; -constexpr decltype(SolverFactory::default_type) SolverFactory::default_type; diff --git a/src/sys/adios_object.cxx b/src/sys/adios_object.cxx new file mode 100644 index 0000000000..477dae14ef --- /dev/null +++ b/src/sys/adios_object.cxx @@ -0,0 +1,98 @@ +#include "bout/build_config.hxx" + +#if BOUT_HAS_ADIOS2 + +#include "bout/adios_object.hxx" +#include "bout/boutexception.hxx" + +#include +#include +#include + +namespace bout { + +static ADIOSPtr adios = nullptr; +static std::unordered_map adiosStreams; + +void ADIOSInit(MPI_Comm comm) { adios = std::make_shared(comm); } + +void ADIOSInit(const std::string configFile, MPI_Comm comm) { + adios = std::make_shared(configFile, comm); +} + +void ADIOSFinalize() { + if (adios == nullptr) { + throw BoutException( + "ADIOS needs to be initialized first before calling ADIOSFinalize()"); + } + adiosStreams.clear(); + adios.reset(); +} + +ADIOSPtr GetADIOSPtr() { + if (adios == nullptr) { + throw BoutException( + "ADIOS needs to be initialized first before calling GetADIOSPtr()"); + } + return adios; +} + +IOPtr GetIOPtr(const std::string IOName) { + auto adios = GetADIOSPtr(); + IOPtr io = nullptr; + try { + io = std::make_shared(adios->AtIO(IOName)); + } catch (std::invalid_argument& e) { + } + return io; +} + +ADIOSStream::~ADIOSStream() { + if (engine) { + if (isInStep) { + engine.EndStep(); + isInStep = false; + } + engine.Close(); + } +} + +ADIOSStream& ADIOSStream::ADIOSGetStream(const std::string& fname) { + auto it = adiosStreams.find(fname); + if (it == adiosStreams.end()) { + it = adiosStreams.emplace(fname, ADIOSStream(fname)).first; + } + return it->second; +} + +void ADIOSSetParameters(const std::string& input, const char delimKeyValue, + const char delimItem, adios2::IO& io) { + auto lf_Trim = [](std::string& input) { + input.erase(0, input.find_first_not_of(" \n\r\t")); // prefixing spaces + input.erase(input.find_last_not_of(" \n\r\t") + 1); // suffixing spaces + }; + + std::istringstream inputSS(input); + std::string parameter; + while (std::getline(inputSS, parameter, delimItem)) { + const size_t position = parameter.find(delimKeyValue); + if (position == parameter.npos) { + throw BoutException("ADIOSSetParameters(): wrong format for IO parameter " + + parameter + ", format must be key" + delimKeyValue + + "value for each entry"); + } + + std::string key = parameter.substr(0, position); + lf_Trim(key); + std::string value = parameter.substr(position + 1); + lf_Trim(value); + if (value.length() == 0) { + throw BoutException("ADIOS2SetParameters: empty value in IO parameter " + parameter + + ", format must be key" + delimKeyValue + "value"); + } + io.SetParameter(key, value); + } +} + +} // namespace bout +#endif //BOUT_HAS_ADIOS2 diff --git a/src/sys/boutexception.cxx b/src/sys/boutexception.cxx index 9b21303cae..825fb37e28 100644 --- a/src/sys/boutexception.cxx +++ b/src/sys/boutexception.cxx @@ -1,11 +1,9 @@ -#include "bout/build_config.hxx" +#include "bout/build_defines.hxx" #include #include #include -#include #include -#include #include #if BOUT_USE_BACKTRACE @@ -13,10 +11,16 @@ #include #endif +#include #include +#include #include +namespace { +const std::string header{"====== Exception thrown ======\n"}; +} + void BoutParallelThrowRhsFail(int status, const char* message) { int allstatus; MPI_Allreduce(&status, &allstatus, 1, MPI_INT, MPI_LOR, BoutComm::get()); @@ -39,7 +43,8 @@ BoutException::~BoutException() { // just clear everything msg_stack.clear(); #if BOUT_USE_BACKTRACE - free(messages); + // Call required for memory allocated by `backtrace_symbols` + free(messages); // NOLINT #endif } @@ -74,18 +79,15 @@ std::string BoutException::getBacktrace() const { const auto syscom = fmt::format( FMT_STRING("addr2line {:p} -Cfpie {:.{}s} 2> /dev/null"), ptr, messages[i], p); // last parameter is the file name of the symbol - FILE* fp = popen(syscom.c_str(), "r"); - if (fp != nullptr) { - char out[1024]; - char* retstr; + FILE* file = popen(syscom.c_str(), "r"); + if (file != nullptr) { + std::array out{}; + char* retstr = nullptr; std::string buf; - do { - retstr = fgets(out, sizeof(out) - 1, fp); - if (retstr != nullptr) { - buf += retstr; - } - } while (retstr != nullptr); - int status = pclose(fp); + while ((retstr = fgets(out.data(), out.size() - 1, file)) != nullptr) { + buf += retstr; + } + int const status = pclose(file); if (status == 0) { backtrace_message += buf; } @@ -100,7 +102,7 @@ std::string BoutException::getBacktrace() const { void BoutException::makeBacktrace() { #if BOUT_USE_BACKTRACE - trace_size = backtrace(trace, TRACE_MAX); - messages = backtrace_symbols(trace, trace_size); + trace_size = backtrace(trace.data(), TRACE_MAX); + messages = backtrace_symbols(trace.data(), trace_size); #endif } diff --git a/src/sys/derivs.cxx b/src/sys/derivs.cxx index 7f629cfbb5..ee9bcbcc2c 100644 --- a/src/sys/derivs.cxx +++ b/src/sys/derivs.cxx @@ -331,8 +331,8 @@ Field3D D2DXDY(const Field3D& f, CELL_LOC outloc, const std::string& method, } Coordinates::FieldMetric D2DXDZ(const Field2D& f, CELL_LOC outloc, - MAYBE_UNUSED(const std::string& method), - MAYBE_UNUSED(const std::string& region)) { + [[maybe_unused]] const std::string& method, + [[maybe_unused]] const std::string& region) { #if BOUT_USE_METRIC_3D Field3D tmp{f}; return D2DXDZ(tmp, outloc, method, region); @@ -356,8 +356,8 @@ Field3D D2DXDZ(const Field3D& f, CELL_LOC outloc, const std::string& method, } Coordinates::FieldMetric D2DYDZ(const Field2D& f, CELL_LOC outloc, - MAYBE_UNUSED(const std::string& method), - MAYBE_UNUSED(const std::string& region)) { + [[maybe_unused]] const std::string& method, + [[maybe_unused]] const std::string& region) { #if BOUT_USE_METRIC_3D Field3D tmp{f}; return D2DYDZ(tmp, outloc, method, region); @@ -369,8 +369,8 @@ Coordinates::FieldMetric D2DYDZ(const Field2D& f, CELL_LOC outloc, #endif } -Field3D D2DYDZ(const Field3D& f, CELL_LOC outloc, MAYBE_UNUSED(const std::string& method), - const std::string& region) { +Field3D D2DYDZ(const Field3D& f, CELL_LOC outloc, + [[maybe_unused]] const std::string& method, const std::string& region) { // If staggering in z, take y-derivative at f's location. const auto y_location = (outloc == CELL_ZLOW or f.getLocation() == CELL_ZLOW) ? CELL_DEFAULT : outloc; @@ -426,9 +426,9 @@ Coordinates::FieldMetric VDDZ(const Field2D& v, const Field2D& f, CELL_LOC outlo } // Note that this is zero because no compression is included -Coordinates::FieldMetric VDDZ(MAYBE_UNUSED(const Field3D& v), const Field2D& f, - CELL_LOC outloc, MAYBE_UNUSED(const std::string& method), - MAYBE_UNUSED(const std::string& region)) { +Coordinates::FieldMetric VDDZ([[maybe_unused]] const Field3D& v, const Field2D& f, + CELL_LOC outloc, [[maybe_unused]] const std::string& method, + [[maybe_unused]] const std::string& region) { #if BOUT_USE_METRIC_3D Field3D tmp{f}; return bout::derivatives::index::VDDZ(v, tmp, outloc, method, region) diff --git a/src/sys/expressionparser.cxx b/src/sys/expressionparser.cxx index 39f8d3bb71..8290a4cae0 100644 --- a/src/sys/expressionparser.cxx +++ b/src/sys/expressionparser.cxx @@ -184,10 +184,29 @@ FieldGeneratorPtr FieldBinary::clone(const list args) { return std::make_shared(args.front(), args.back(), op); } +/// Convert a real value to a Boolean +/// Throw exception if `rval` isn't close to 0 or 1 +bool toBool(BoutReal rval) { + int ival = ROUND(rval); + if ((fabs(rval - static_cast(ival)) > 1e-3) or (ival < 0) or (ival > 1)) { + throw BoutException(_("Boolean operator argument {:e} is not a bool"), rval); + } + return ival == 1; +} + BoutReal FieldBinary::generate(const Context& ctx) { BoutReal lval = lhs->generate(ctx); BoutReal rval = rhs->generate(ctx); + switch (op) { + case '|': // Logical OR + return (toBool(lval) or toBool(rval)) ? 1.0 : 0.0; + case '&': // Logical AND + return (toBool(lval) and toBool(rval)) ? 1.0 : 0.0; + case '>': // Comparison + return (lval > rval) ? 1.0 : 0.0; + case '<': + return (lval < rval) ? 1.0 : 0.0; case '+': return lval + rval; case '-': @@ -203,10 +222,30 @@ BoutReal FieldBinary::generate(const Context& ctx) { throw ParseException("Unknown binary operator '{:c}'", op); } +class LogicalNot : public FieldGenerator { +public: + /// Logically negate a boolean expression + LogicalNot(FieldGeneratorPtr expr) : expr(expr) {} + + /// Evaluate expression, check it's a bool, and return 1 or 0 + double generate(const Context& ctx) override { + return toBool(expr->generate(ctx)) ? 0.0 : 1.0; + } + + std::string str() const override { return "!"s + expr->str(); } + +private: + FieldGeneratorPtr expr; +}; + ///////////////////////////////////////////// ExpressionParser::ExpressionParser() { // Add standard binary operations + addBinaryOp('|', std::make_shared(nullptr, nullptr, '|'), 3); + addBinaryOp('&', std::make_shared(nullptr, nullptr, '&'), 5); + addBinaryOp('<', std::make_shared(nullptr, nullptr, '<'), 7); + addBinaryOp('>', std::make_shared(nullptr, nullptr, '>'), 7); addBinaryOp('+', std::make_shared(nullptr, nullptr, '+'), 10); addBinaryOp('-', std::make_shared(nullptr, nullptr, '-'), 10); addBinaryOp('*', std::make_shared(nullptr, nullptr, '*'), 20); @@ -482,6 +521,11 @@ FieldGeneratorPtr ExpressionParser::parsePrimary(LexInfo& lex) const { // Don't eat the minus, and return an implicit zero return std::make_shared(0.0); } + case '!': { + // Logical not + lex.nextToken(); // Eat '!' + return std::make_shared(parsePrimary(lex)); + } case '(': { return parseParenExpr(lex); } diff --git a/src/sys/generator_context.cxx b/src/sys/generator_context.cxx index 236de7f95b..25274e8107 100644 --- a/src/sys/generator_context.cxx +++ b/src/sys/generator_context.cxx @@ -45,5 +45,8 @@ Context::Context(const BoundaryRegion* bndry, int iz, CELL_LOC loc, BoutReal t, parameters["t"] = t; } +Context::Context(BoutReal x, BoutReal y, BoutReal z, Mesh* msh, BoutReal t) + : localmesh(msh), parameters{{"x", x}, {"y", y}, {"z", z}, {"t", t}} {} + } // namespace generator } // namespace bout diff --git a/src/sys/hyprelib.cxx b/src/sys/hyprelib.cxx index e833162726..7bdeaa47cf 100644 --- a/src/sys/hyprelib.cxx +++ b/src/sys/hyprelib.cxx @@ -27,7 +27,7 @@ static constexpr auto BOUT_HYPRE_MEMORY = HYPRE_MEMORY_HOST; #endif HypreLib::HypreLib() { - BOUT_OMP(critical(HypreLib)) + BOUT_OMP_SAFE(critical(HypreLib)) { if (count == 0) { // Initialise once output_progress.write("Initialising Hypre\n"); @@ -39,16 +39,16 @@ HypreLib::HypreLib() { } } -HypreLib::HypreLib(MAYBE_UNUSED() const HypreLib& other) noexcept { - BOUT_OMP(critical(HypreLib)) +HypreLib::HypreLib([[maybe_unused]] const HypreLib& other) noexcept { + BOUT_OMP_SAFE(critical(HypreLib)) { // No need to initialise Hypre, because it must already be initialised count++; // Copying, so increase count } } -HypreLib::HypreLib(MAYBE_UNUSED() HypreLib&& other) noexcept { - BOUT_OMP(critical(HypreLib)) +HypreLib::HypreLib([[maybe_unused]] HypreLib&& other) noexcept { + BOUT_OMP_SAFE(critical(HypreLib)) { // No need to initialise Hypre, because it must already be initialised count++; // Creating a new Hyprelib object; other will be deleted @@ -56,7 +56,7 @@ HypreLib::HypreLib(MAYBE_UNUSED() HypreLib&& other) noexcept { } HypreLib::~HypreLib() { - BOUT_OMP(critical(HypreLib)) + BOUT_OMP_SAFE(critical(HypreLib)) { count--; if (count == 0) { @@ -67,7 +67,7 @@ HypreLib::~HypreLib() { } void HypreLib::cleanup() { - BOUT_OMP(critical(HypreLib)) + BOUT_OMP_SAFE(critical(HypreLib)) { if (count > 0) { output << "Finalising Hypre. Warning: Instances of HypreLib still exist.\n"; diff --git a/src/sys/makefile b/src/sys/makefile deleted file mode 100644 index 04d39971cf..0000000000 --- a/src/sys/makefile +++ /dev/null @@ -1,14 +0,0 @@ - -BOUT_TOP = ../.. -DIRS = options -SOURCEC = bout_types.cxx boutexception.cxx derivs.cxx \ - msg_stack.cxx options.cxx output.cxx \ - utils.cxx optionsreader.cxx boutcomm.cxx \ - timer.cxx range.cxx petsclib.cxx expressionparser.cxx \ - slepclib.cxx type_name.cxx generator_context.cxx \ - hyprelib.cxx - -SOURCEH = $(SOURCEC:%.cxx=%.hxx) globals.hxx bout_types.hxx multiostream.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/sys/msg_stack.cxx b/src/sys/msg_stack.cxx index 6ea4c15a8b..502836324c 100644 --- a/src/sys/msg_stack.cxx +++ b/src/sys/msg_stack.cxx @@ -58,7 +58,7 @@ void MsgStack::pop() { if (position <= 0) { return; } - BOUT_OMP(single) + BOUT_OMP_SAFE(single) { --position; } } @@ -78,7 +78,7 @@ void MsgStack::pop(int id) { } void MsgStack::clear() { - BOUT_OMP(single) + BOUT_OMP_SAFE(single) { stack.clear(); position = 0; @@ -86,7 +86,7 @@ void MsgStack::clear() { } void MsgStack::dump() { - BOUT_OMP(single) + BOUT_OMP_SAFE(single) { output << this->getDump(); } } diff --git a/src/sys/options.cxx b/src/sys/options.cxx index 8b49b1f3f1..e2f39542fd 100644 --- a/src/sys/options.cxx +++ b/src/sys/options.cxx @@ -1,14 +1,34 @@ -#include -#include // Used for parsing expressions -#include -#include -#include - +#include "bout/options.hxx" + +#include "bout/array.hxx" +#include "bout/bout_types.hxx" +#include "bout/boutexception.hxx" +#include "bout/field2d.hxx" +#include "bout/field3d.hxx" +#include "bout/field_factory.hxx" // Used for parsing expressions +#include "bout/fieldperp.hxx" +#include "bout/output.hxx" +#include "bout/sys/expressionparser.hxx" +#include "bout/sys/gettext.hxx" +#include "bout/sys/type_name.hxx" +#include "bout/sys/variant.hxx" +#include "bout/traits.hxx" +#include "bout/unused.hxx" +#include "bout/utils.hxx" + +#include #include +#include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include /// The source label given to default values const std::string Options::DEFAULT_SOURCE{_("default")}; @@ -19,28 +39,36 @@ std::string Options::getDefaultSource() { return DEFAULT_SOURCE; } /// having been used constexpr auto conditionally_used_attribute = "conditionally used"; -Options* Options::root_instance{nullptr}; - Options& Options::root() { - if (root_instance == nullptr) { - // Create the singleton - root_instance = new Options(); - } - return *root_instance; + static Options root_instance; + return root_instance; } -void Options::cleanup() { - if (root_instance == nullptr) { - return; +void Options::cleanup() { root() = Options{}; } + +Options Options::copy() const { + Options result; + + result.value = value; + result.attributes = attributes; + result.parent_instance = parent_instance; + result.full_name = full_name; + result.is_section = is_section; + result.value_used = value_used; + + // Recursively copy children + for (const auto& child_it : children) { + auto pair_it = result.children.emplace(child_it.first, child_it.second.copy()); + Options& child = pair_it.first->second; + child.parent_instance = &result; } - delete root_instance; - root_instance = nullptr; + return result; } -Options::Options(const Options& other) - : value(other.value), attributes(other.attributes), - parent_instance(other.parent_instance), full_name(other.full_name), - is_section(other.is_section), children(other.children), +Options::Options(Options&& other) noexcept + : value(std::move(other.value)), attributes(std::move(other.attributes)), + parent_instance(other.parent_instance), full_name(std::move(other.full_name)), + is_section(other.is_section), children(std::move(other.children)), value_used(other.value_used) { // Ensure that this is the parent of all children, @@ -55,39 +83,25 @@ Options::Options(const char* value) { assign(value); } -Options::Options(std::initializer_list> values) { - // Yes, this looks bad, but bear with me... The _only_ way to - // construct a nested initializer_list is inside-out, from the - // bottom of the tree structure. Unfortunately, this is very much - // not how you would want to construct the tree of options, as we - // don't have the parent section's name as we construct each - // child. Therefore, when we _do_ construct the parent, we'll need - // to recursively step down the tree, prepending the parent's name - // to each child. Rather than have a private member to do that, we - // use a lambda. And to make that lambda recursive, we need to have - // a nested lambda. - auto append_section_name = [](auto& children, const std::string& section_name) { - auto append_impl = [](auto& children, const std::string& section_name, - auto& append_ref) mutable -> void { - for (auto& child : children) { - child.second.full_name = - fmt::format("{}:{}", section_name, child.second.full_name); - if (child.second.is_section) { - append_ref(child.second.children, section_name, append_ref); - } - } - }; - append_impl(children, section_name, append_impl); - }; - - for (auto& value : values) { - (*this)[value.first] = value.second; - // value.second was constructed from the "bare" `Options(T)` so - // doesn't have `full_name` set. This clobbers - // `(*this)[value.first].full_name` in the copy constructor, so we - // need to explicitly set it again - (*this)[value.first].full_name = value.first; - append_section_name((*this)[value.first].children, value.first); +Options::Options(InitializerList values, Options* parent_instance, + std::string section_name) + : parent_instance(parent_instance), full_name(std::move(section_name)), + is_section(true) { + for (const auto& value_it : values) { + std::string child_name = full_name.empty() + ? value_it.first + : fmt::format("{}:{}", full_name, value_it.first); + if (value_it.second.children.size() != 0) { + // A section, so construct with an initializer_list + children.emplace(value_it.first, + Options(value_it.second.children, this, std::move(child_name))); + } else { + // A value + auto pair_it = + children.emplace(value_it.first, Options(this, std::move(child_name))); + Options& child = pair_it.first->second; + child._set_no_check(value_it.second.value, ""); + } } } @@ -107,15 +121,15 @@ Options& Options::operator[](const std::string& name) { } // If name is compound, e.g. "section:subsection", then split the name - auto subsection_split = name.find(":"); + auto subsection_split = name.find(':'); if (subsection_split != std::string::npos) { return (*this)[name.substr(0, subsection_split)][name.substr(subsection_split + 1)]; } // Find and return if already exists - auto it = children.find(name); - if (it != children.end()) { - return it->second; + auto child = children.find(name); + if (child != children.end()) { + return child->second; } // Doesn't exist yet, so add @@ -146,19 +160,19 @@ const Options& Options::operator[](const std::string& name) const { } // If name is compound, e.g. "section:subsection", then split the name - auto subsection_split = name.find(":"); + auto subsection_split = name.find(':'); if (subsection_split != std::string::npos) { return (*this)[name.substr(0, subsection_split)][name.substr(subsection_split + 1)]; } // Find and return if already exists - auto it = children.find(name); - if (it == children.end()) { + auto child = children.find(name); + if (child == children.end()) { // Doesn't exist throw BoutException(_("Option {:s}:{:s} does not exist"), full_name, name); } - return it->second; + return child->second; } std::multiset @@ -208,7 +222,13 @@ Options::fuzzyFind(const std::string& name, std::string::size_type distance) con return matches; } +Options::Options(const Options& other) { (*this) = other.copy(); } + Options& Options::operator=(const Options& other) { + if (this == &other) { + return *this; + } + // Note: Here can't do copy-and-swap because pointers to parents are stored value = other.value; @@ -232,6 +252,28 @@ Options& Options::operator=(const Options& other) { return *this; } +Options& Options::operator=(Options&& other) noexcept { + if (this == &other) { + return *this; + } + + // Note: Here can't do copy-and-swap because pointers to parents are stored + + value = std::move(other.value); + attributes = std::move(other.attributes); + full_name = std::move(other.full_name); + is_section = other.is_section; + children = std::move(other.children); + value_used = other.value_used; + + // Ensure that this is the parent of all children, + // otherwise will point to the original Options instance + for (auto& child : children) { + child.second.parent_instance = this; + } + return *this; +} + bool Options::isSet() const { // Only values can be set/unset if (is_section) { @@ -247,18 +289,17 @@ bool Options::isSet() const { } bool Options::isSection(const std::string& name) const { - if (name == "") { + if (name.empty()) { // Test this object return is_section; } // Is there a child section? - auto it = children.find(name); - if (it == children.end()) { + const auto child = children.find(name); + if (child == children.end()) { return false; - } else { - return it->second.isSection(); } + return child->second.isSection(); } template <> @@ -296,27 +337,6 @@ void Options::assign<>(Tensor val, std::string source) { _set_no_check(std::move(val), std::move(source)); } -template <> -std::string Options::as(const std::string& UNUSED(similar_to)) const { - if (is_section) { - throw BoutException(_("Option {:s} has no value"), full_name); - } - - // Mark this option as used - value_used = true; - - std::string result = bout::utils::variantToString(value); - - output_info << _("\tOption ") << full_name << " = " << result; - if (attributes.count("source")) { - // Specify the source of the setting - output_info << " (" << bout::utils::variantToString(attributes.at("source")) << ")"; - } - output_info << endl; - - return result; -} - namespace { /// Use FieldFactory to evaluate expression double parseExpression(const Options::ValueType& value, const Options* options, @@ -336,22 +356,50 @@ double parseExpression(const Options::ValueType& value, const Options* options, full_name, bout::utils::variantToString(value), error.what()); } } + +/// Helper function to print `key = value` with optional source +template +void printNameValueSourceLine(const Options& option, const T& value) { + output_info.write(_("\tOption {} = {}"), option.str(), value); + if (option.hasAttribute("source")) { + // Specify the source of the setting + output_info.write(" ({})", + bout::utils::variantToString(option.attributes.at("source"))); + } + output_info.write("\n"); +} } // namespace +template <> +std::string Options::as(const std::string& UNUSED(similar_to)) const { + if (is_section) { + throw BoutException(_("Option {:s} has no value"), full_name); + } + + // Mark this option as used + value_used = true; + + std::string result = bout::utils::variantToString(value); + + printNameValueSourceLine(*this, result); + + return result; +} + template <> int Options::as(const int& UNUSED(similar_to)) const { if (is_section) { throw BoutException(_("Option {:s} has no value"), full_name); } - int result; + int result = 0; if (bout::utils::holds_alternative(value)) { result = bout::utils::get(value); } else { // Cases which get a BoutReal then check if close to an integer - BoutReal rval; + BoutReal rval = BoutNaN; if (bout::utils::holds_alternative(value)) { rval = bout::utils::get(value); @@ -376,12 +424,7 @@ int Options::as(const int& UNUSED(similar_to)) const { value_used = true; - output_info << _("\tOption ") << full_name << " = " << result; - if (attributes.count("source")) { - // Specify the source of the setting - output_info << " (" << bout::utils::variantToString(attributes.at("source")) << ")"; - } - output_info << endl; + printNameValueSourceLine(*this, result); return result; } @@ -392,7 +435,7 @@ BoutReal Options::as(const BoutReal& UNUSED(similar_to)) const { throw BoutException(_("Option {:s} has no value"), full_name); } - BoutReal result; + BoutReal result = BoutNaN; if (bout::utils::holds_alternative(value)) { result = static_cast(bout::utils::get(value)); @@ -411,12 +454,7 @@ BoutReal Options::as(const BoutReal& UNUSED(similar_to)) const { // Mark this option as used value_used = true; - output_info << _("\tOption ") << full_name << " = " << result; - if (attributes.count("source")) { - // Specify the source of the setting - output_info << " (" << bout::utils::variantToString(attributes.at("source")) << ")"; - } - output_info << endl; + printNameValueSourceLine(*this, result); return result; } @@ -427,25 +465,22 @@ bool Options::as(const bool& UNUSED(similar_to)) const { throw BoutException(_("Option {:s} has no value"), full_name); } - bool result; + bool result = false; if (bout::utils::holds_alternative(value)) { result = bout::utils::get(value); } else if (bout::utils::holds_alternative(value)) { - // case-insensitve check, so convert string to lower case - const auto strvalue = lowercase(bout::utils::get(value)); - - if ((strvalue == "y") or (strvalue == "yes") or (strvalue == "t") - or (strvalue == "true") or (strvalue == "1")) { - result = true; - } else if ((strvalue == "n") or (strvalue == "no") or (strvalue == "f") - or (strvalue == "false") or (strvalue == "0")) { - result = false; - } else { - throw BoutException(_("\tOption '{:s}': Boolean expected. Got '{:s}'\n"), full_name, - strvalue); + // Parse as floating point because that's the only type the parser understands + const BoutReal rval = parseExpression(value, this, "bool", full_name); + + // Check that the result is either close to 1 (true) or close to 0 (false) + const int ival = ROUND(rval); + if ((fabs(rval - static_cast(ival)) > 1e-3) or (ival < 0) or (ival > 1)) { + throw BoutException(_("Value for option {:s} = {:e} is not a bool"), full_name, + rval); } + result = ival == 1; } else { throw BoutException(_("Value for option {:s} cannot be converted to a bool"), full_name); @@ -453,13 +488,7 @@ bool Options::as(const bool& UNUSED(similar_to)) const { value_used = true; - output_info << _("\tOption ") << full_name << " = " << toString(result); - - if (attributes.count("source")) { - // Specify the source of the setting - output_info << " (" << bout::utils::variantToString(attributes.at("source")) << ")"; - } - output_info << endl; + printNameValueSourceLine(*this, toString(result)); return result; } @@ -493,7 +522,7 @@ Field3D Options::as(const Field3D& similar_to) const { if (bout::utils::holds_alternative(value) or bout::utils::holds_alternative(value)) { - BoutReal scalar_value = + const BoutReal scalar_value = bout::utils::variantStaticCastOrThrow(value); // Get metadata from similar_to, fill field with scalar_value @@ -523,6 +552,11 @@ Field3D Options::as(const Field3D& similar_to) const { // If dimension sizes not the same, may be able // to select a region from it using Mesh e.g. if this // is from the input grid file. + const auto [tx, ty, tz] = tensor.shape(); + throw BoutException("Size mismatch for option {:s}: Tensor ({}, {}, {}) cannot be " + "converted to Field3D ({}, {}, {})", + full_name, tx, ty, tz, localmesh->LocalNx, localmesh->LocalNy, + localmesh->LocalNz); } throw BoutException(_("Value for option {:s} cannot be converted to a Field3D"), @@ -549,7 +583,7 @@ Field2D Options::as(const Field2D& similar_to) const { if (bout::utils::holds_alternative(value) or bout::utils::holds_alternative(value)) { - BoutReal scalar_value = + const BoutReal scalar_value = bout::utils::variantStaticCastOrThrow(value); // Get metadata from similar_to, fill field with scalar_value @@ -601,7 +635,7 @@ FieldPerp Options::as(const FieldPerp& similar_to) const { if (bout::utils::holds_alternative(value) or bout::utils::holds_alternative(value)) { - BoutReal scalar_value = + const BoutReal scalar_value = bout::utils::variantStaticCastOrThrow(value); // Get metadata from similar_to, fill field with scalar_value @@ -686,7 +720,7 @@ struct ConvertContainer { Container operator()(const Container& value) { return value; } template - Container operator()(MAYBE_UNUSED(const Other& value)) { + Container operator()([[maybe_unused]] const Other& value) { throw BoutException(error_message); } @@ -713,12 +747,7 @@ Array Options::as>(const Array& similar_to) // Mark this option as used value_used = true; - output_info << _("\tOption ") << full_name << " = Array"; - if (hasAttribute("source")) { - // Specify the source of the setting - output_info << " (" << bout::utils::variantToString(attributes.at("source")) << ")"; - } - output_info << endl; + printNameValueSourceLine(*this, "Array"); return result; } @@ -740,12 +769,7 @@ Matrix Options::as>(const Matrix& similar_t // Mark this option as used value_used = true; - output_info << _("\tOption ") << full_name << " = Matrix"; - if (hasAttribute("source")) { - // Specify the source of the setting - output_info << " (" << bout::utils::variantToString(attributes.at("source")) << ")"; - } - output_info << endl; + printNameValueSourceLine(*this, "Matrix"); return result; } @@ -767,12 +791,7 @@ Tensor Options::as>(const Tensor& similar_t // Mark this option as used value_used = true; - output_info << _("\tOption ") << full_name << " = Tensor"; - if (hasAttribute("source")) { - // Specify the source of the setting - output_info << " (" << bout::utils::variantToString(attributes.at("source")) << ")"; - } - output_info << endl; + printNameValueSourceLine(*this, "Tensor"); return result; } @@ -808,7 +827,7 @@ Options Options::getUnused(const std::vector& exclude_sources) cons // Copy this object, and then we're going to chuck out everything // that has been used. This turns out to be easier than copying just // the unused options into an empty instance - Options unused = *this; + Options unused = this->copy(); if (unused.isValue()) { // If this is from an excluded source, count it as being used @@ -858,7 +877,7 @@ Options Options::getUnused(const std::vector& exclude_sources) cons } void Options::printUnused() const { - Options unused = getUnused(); + const Options unused = getUnused(); // Two cases: single value, or a section. If it's a single value, // we can check it directly. If it's a section, we can see if it has @@ -882,9 +901,9 @@ void Options::cleanCache() { FieldFactory::get()->cleanCache(); } std::map Options::subsections() const { std::map sections; - for (const auto& it : children) { - if (it.second.is_section) { - sections[it.first] = &it.second; + for (const auto& child : children) { + if (child.second.is_section) { + sections[child.first] = &child.second; } } return sections; @@ -915,8 +934,8 @@ fmt::format_parse_context::iterator bout::details::OptionsFormatterBase::parse(fmt::format_parse_context& ctx) { const auto* closing_brace = std::find(ctx.begin(), ctx.end(), '}'); - std::for_each(ctx.begin(), closing_brace, [&](auto it) { - switch (it) { + std::for_each(ctx.begin(), closing_brace, [&](auto ctx_opt) { + switch (ctx_opt) { case 'd': docstrings = true; break; @@ -950,7 +969,7 @@ bout::details::OptionsFormatterBase::parse(fmt::format_parse_context& ctx) { fmt::format_context::iterator bout::details::OptionsFormatterBase::format(const Options& options, - fmt::format_context& ctx) { + fmt::format_context& ctx) const { const auto conditionally_used = [](const Options& option) -> bool { if (not option.hasAttribute(conditionally_used_attribute)) { @@ -1014,7 +1033,7 @@ bout::details::OptionsFormatterBase::format(const Options& options, // Only print section headers if the section has a name and it has // non-section children - const auto children = options.getChildren(); + const auto& children = options.getChildren(); const bool has_child_values = std::any_of(children.begin(), children.end(), [](const auto& child) { return child.second.isValue(); }); @@ -1059,7 +1078,7 @@ void checkForUnusedOptions() { void checkForUnusedOptions(const Options& options, const std::string& data_dir, const std::string& option_file) { - Options unused = options.getUnused(); + const Options unused = options.getUnused(); if (not unused.getChildren().empty()) { // Construct a string with all the fuzzy matches for each unused option diff --git a/src/sys/options/makefile b/src/sys/options/makefile deleted file mode 100644 index e38608b68c..0000000000 --- a/src/sys/options/makefile +++ /dev/null @@ -1,7 +0,0 @@ -BOUT_TOP = ../../.. -SOURCEC = options_ini.cxx options_netcdf.cxx - -SOURCEH = $(SOURCEC:%.cxx=%.hxx) globals.hxx bout_types.hxx multiostream.hxx -TARGET = lib - -include $(BOUT_TOP)/make.config diff --git a/src/sys/options/optionparser.hxx b/src/sys/options/optionparser.hxx index ff5bb61a6f..bc61ef7297 100644 --- a/src/sys/options/optionparser.hxx +++ b/src/sys/options/optionparser.hxx @@ -39,8 +39,8 @@ class OptionParser; -#ifndef __OPTIONPARSER_H__ -#define __OPTIONPARSER_H__ +#ifndef BOUT_OPTIONPARSER_H +#define BOUT_OPTIONPARSER_H #include "bout/bout_types.hxx" #include "bout/options.hxx" @@ -61,4 +61,4 @@ public: private: }; -#endif // __OPTIONPARSER_H__ +#endif // BOUT_OPTIONPARSER_H diff --git a/src/sys/options/options_adios.cxx b/src/sys/options/options_adios.cxx new file mode 100644 index 0000000000..88df92df04 --- /dev/null +++ b/src/sys/options/options_adios.cxx @@ -0,0 +1,631 @@ +#include "bout/build_config.hxx" + +#if BOUT_HAS_ADIOS2 + +#include "options_adios.hxx" +#include "bout/adios_object.hxx" + +#include "bout/bout.hxx" +#include "bout/boutexception.hxx" +#include "bout/globals.hxx" +#include "bout/mesh.hxx" +#include "bout/sys/timer.hxx" + +#include "adios2.h" +#include +#include +#include + +namespace bout { +/// Name of the attribute used to track individual variable's time indices +constexpr auto current_time_index_name = "current_time_index"; + +OptionsADIOS::OptionsADIOS(Options& options) : OptionsIO(options) { + if (options["file"].doc("File name. Defaults to /.pb").isSet()) { + filename = options["file"].as(); + } else { + // Both path and prefix must be set + filename = fmt::format("{}/{}.bp", options["path"].as(), + options["prefix"].as()); + } + + file_mode = (options["append"].doc("Append to existing file?").withDefault(false)) + ? FileMode::append + : FileMode::replace; + + singleWriteFile = options["singleWriteFile"].withDefault(false); +} + +template +Options readVariable(adios2::Engine& reader, adios2::IO& io, const std::string& name, + const std::string& type) { + std::vector data; + adios2::Variable variable = io.InquireVariable(name); + + using bout::globals::mesh; + + if (variable.ShapeID() == adios2::ShapeID::GlobalValue) { + T value; + reader.Get(variable, &value, adios2::Mode::Sync); + return Options(value); + } + + if (variable.ShapeID() == adios2::ShapeID::LocalArray) { + throw std::invalid_argument( + "ADIOS reader did not implement reading local arrays like " + type + " " + name + + " in file " + reader.Name()); + } + + if (type != "double" && type != "float") { + throw std::invalid_argument( + "ADIOS reader did not implement reading arrays that are not double/float type. " + "Found " + + type + " " + name + " in file " + reader.Name()); + } + + if (type == "double" && sizeof(BoutReal) != sizeof(double)) { + throw std::invalid_argument( + "ADIOS does not allow for implicit type conversions. BoutReal type is " + "float but found " + + type + " " + name + " in file " + reader.Name()); + } + + if (type == "float" && sizeof(BoutReal) != sizeof(float)) { + throw std::invalid_argument( + "ADIOS reader does not allow for implicit type conversions. BoutReal type is " + "double but found " + + type + " " + name + " in file " + reader.Name()); + } + + auto dims = variable.Shape(); + auto ndims = dims.size(); + adios2::Variable variableD = io.InquireVariable(name); + + switch (ndims) { + case 1: { + Array value(static_cast(dims[0])); + BoutReal* data = value.begin(); + reader.Get(variableD, data, adios2::Mode::Sync); + return Options(value); + } + case 2: { + // This could be a Field2D (XY) or FieldPerp (XZ) + // Here we look for array sizes, but if Y and Z dimensions are the same size + // then it's ambiguous. This method also depends on the global Mesh object. + // Some possibilities: + // - Add an attribute to specify field type or dimension labels + // - Load all the data, and select a region when converting to a Field in Options + // - Add a lazy loading type to Options, and load data when needed + if ((static_cast(dims[0]) == mesh->GlobalNx) + and (static_cast(dims[1]) == mesh->GlobalNy)) { + // Probably a Field2D + + // Read just the local piece of the array + Matrix value(mesh->LocalNx, mesh->LocalNy); + + // Offset of this processor's data into the global array + adios2::Dims start = {static_cast(mesh->MapGlobalX), + static_cast(mesh->MapGlobalY)}; + + // The size of the mapped region + adios2::Dims count = {static_cast(mesh->MapCountX), + static_cast(mesh->MapCountY)}; + + // Where the actual data starts in data pointer (to exclude ghost cells) + adios2::Dims memStart = {static_cast(mesh->MapLocalX), + static_cast(mesh->MapLocalY)}; + + // The actual size of data pointer in memory (including ghost cells) + adios2::Dims memCount = {static_cast(mesh->LocalNx), + static_cast(mesh->LocalNy)}; + variableD.SetSelection({start, count}); + variableD.SetMemorySelection({memStart, memCount}); + BoutReal* data = value.begin(); + reader.Get(variableD, data, adios2::Mode::Sync); + return Options(value); + } + if ((static_cast(dims[0]) == mesh->GlobalNx) + and (static_cast(dims[2]) == mesh->GlobalNz)) { + // Probably a FieldPerp + + // Read just the local piece of the array + Matrix value(mesh->LocalNx, mesh->LocalNz); + + // Offset of this processor's data into the global array + adios2::Dims start = {static_cast(mesh->MapGlobalX), + static_cast(mesh->MapGlobalZ)}; + + // The size of the mapped region + adios2::Dims count = {static_cast(mesh->MapCountX), + static_cast(mesh->MapCountZ)}; + + // Where the actual data starts in data pointer (to exclude ghost cells) + adios2::Dims memStart = {static_cast(mesh->MapLocalX), + static_cast(mesh->MapLocalZ)}; + + // The actual size of data pointer in memory (including ghost cells) + adios2::Dims memCount = {static_cast(mesh->LocalNx), + static_cast(mesh->LocalNz)}; + variableD.SetSelection({start, count}); + variableD.SetMemorySelection({memStart, memCount}); + BoutReal* data = value.begin(); + reader.Get(variableD, data, adios2::Mode::Sync); + return Options(value); + } + Matrix value(static_cast(dims[0]), static_cast(dims[1])); + BoutReal* data = value.begin(); + reader.Get(variableD, data, adios2::Mode::Sync); + return Options(value); + } + case 3: { + if ((static_cast(dims[0]) == mesh->GlobalNx) + and (static_cast(dims[1]) == mesh->GlobalNy) + and (static_cast(dims[2]) == mesh->GlobalNz)) { + // Global array. Read just this processor's part of it + + Tensor value(mesh->LocalNx, mesh->LocalNy, mesh->LocalNz); + + // Offset of this processor's data into the global array + adios2::Dims start = {static_cast(mesh->MapGlobalX), + static_cast(mesh->MapGlobalY), + static_cast(mesh->MapGlobalZ)}; + + // The size of the mapped region + adios2::Dims count = {static_cast(mesh->MapCountX), + static_cast(mesh->MapCountY), + static_cast(mesh->MapCountZ)}; + + // Where the actual data starts in data pointer (to exclude ghost cells) + adios2::Dims memStart = {static_cast(mesh->MapLocalX), + static_cast(mesh->MapLocalY), + static_cast(mesh->MapLocalZ)}; + + // The actual size of data pointer in memory (including ghost cells) + adios2::Dims memCount = {static_cast(mesh->LocalNx), + static_cast(mesh->LocalNy), + static_cast(mesh->LocalNz)}; + + variableD.SetSelection({start, count}); + variableD.SetMemorySelection({memStart, memCount}); + BoutReal* data = value.begin(); + reader.Get(variableD, data, adios2::Mode::Sync); + return Options(value); + } + // Doesn't match global array size. + // Read the entire array, in case it can be handled later + Tensor value(static_cast(dims[0]), static_cast(dims[1]), + static_cast(dims[2])); + BoutReal* data = value.begin(); + reader.Get(variableD, data, adios2::Mode::Sync); + return Options(value); + } + } + throw BoutException("ADIOS reader failed to read '{}' of dimension {} in file '{}'", + name, ndims, reader.Name()); +} + +Options readVariable(adios2::Engine& reader, adios2::IO& io, const std::string& name, + const std::string& type) { +#define declare_template_instantiation(T) \ + if (type == adios2::GetType()) { \ + return readVariable(reader, io, name, type); \ + } + ADIOS2_FOREACH_ATTRIBUTE_PRIMITIVE_STDTYPE_1ARG(declare_template_instantiation) + declare_template_instantiation(std::string) +#undef declare_template_instantiation + output_warn.write("ADIOS readVariable can't read type '{}' (variable '{}')", type, + name); + return Options{}; +} + +bool readAttribute(adios2::IO& io, const std::string& name, const std::string& type, + Options& result) { + // Attribute is the part of 'name' after the last '/' separator + std::string attrname; + auto pos = name.find_last_of('/'); + if (pos == std::string::npos) { + attrname = name; + } else { + attrname = name.substr(pos + 1); + } + +#define declare_template_instantiation(T) \ + if (type == adios2::GetType()) { \ + adios2::Attribute a = io.InquireAttribute(name); \ + result.attributes[attrname] = *a.Data().data(); \ + return true; \ + } + // Only some types of attributes are supported + //declare_template_instantiation(bool) + declare_template_instantiation(int) declare_template_instantiation(BoutReal) + declare_template_instantiation(std::string) +#undef declare_template_instantiation + output_warn.write("ADIOS readAttribute can't read type '{}' (variable '{}')", + type, name); + return false; +} + +Options OptionsADIOS::read() { + Timer timer("io"); + + // Open file + ADIOSPtr adiosp = GetADIOSPtr(); + adios2::IO io; + std::string ioname = "read_" + filename; + try { + io = adiosp->AtIO(ioname); + } catch (const std::invalid_argument& e) { + io = adiosp->DeclareIO(ioname); + } + + adios2::Engine reader = io.Open(filename, adios2::Mode::ReadRandomAccess); + if (!reader) { + throw BoutException("Could not open ADIOS file '{:s}' for reading", filename); + } + + Options result; + + // Iterate over all variables + for (const auto& varpair : io.AvailableVariables()) { + const auto& var_name = varpair.first; // Name of the variable + + auto it = varpair.second.find("Type"); + const std::string& var_type = it->second; + + Options* varptr = &result; + for (const auto& piece : strsplit(var_name, '/')) { + varptr = &(*varptr)[piece]; // Navigate to subsection if needed + } + Options& var = *varptr; + + // Note: Copying the value rather than simple assignment is used + // because the Options assignment operator overwrites full_name. + var = 0; // Setting is_section to false + var.value = readVariable(reader, io, var_name, var_type).value; + var.attributes["source"] = filename; + + // Get variable attributes + for (const auto& attpair : io.AvailableAttributes(var_name, "/", true)) { + const auto& att_name = attpair.first; // Attribute name + const auto& att = attpair.second; // attribute params + + auto it = att.find("Type"); + const std::string& att_type = it->second; + readAttribute(io, att_name, att_type, var); + } + } + + reader.Close(); + + return result; +} + +void OptionsADIOS::verifyTimesteps() const { + ADIOSStream& stream = ADIOSStream::ADIOSGetStream(filename); + stream.engine.EndStep(); + stream.isInStep = false; + return; +} + +/// Visit a variant type, and put the data into a NcVar +struct ADIOSPutVarVisitor { + ADIOSPutVarVisitor(const std::string& name, ADIOSStream& stream) + : varname(name), stream(stream) {} + template + void operator()(const T& value) { + adios2::Variable var = stream.GetValueVariable(varname); + stream.engine.Put(var, value); + } + +private: + const std::string& varname; + ADIOSStream& stream; +}; + +template <> +void ADIOSPutVarVisitor::operator()(const bool& value) { + // Scalars are only written from processor 0 + if (BoutComm::rank() != 0) { + return; + } + adios2::Variable var = stream.GetValueVariable(varname); + stream.engine.Put(var, static_cast(value)); +} + +template <> +void ADIOSPutVarVisitor::operator()(const int& value) { + // Scalars are only written from processor 0 + if (BoutComm::rank() != 0) { + return; + } + adios2::Variable var = stream.GetValueVariable(varname); + stream.engine.Put(var, value); +} + +template <> +void ADIOSPutVarVisitor::operator()(const BoutReal& value) { + // Scalars are only written from processor 0 + if (BoutComm::rank() != 0) { + return; + } + adios2::Variable var = stream.GetValueVariable(varname); + stream.engine.Put(var, value); +} + +template <> +void ADIOSPutVarVisitor::operator()(const std::string& value) { + // Scalars are only written from processor 0 + if (BoutComm::rank() != 0) { + return; + } + adios2::Variable var = stream.GetValueVariable(varname); + stream.engine.Put(var, value, adios2::Mode::Sync); +} + +template <> +void ADIOSPutVarVisitor::operator()(const Field2D& value) { + // Get the mesh that describes how local data relates to global arrays + auto mesh = value.getMesh(); + + // The global size of this array includes boundary cells but not communication guard cells. + // In general this array will be sparse because it may have gaps. + adios2::Dims shape = {static_cast(mesh->GlobalNx), + static_cast(mesh->GlobalNy)}; + + // Offset of this processor's data into the global array + adios2::Dims start = {static_cast(mesh->MapGlobalX), + static_cast(mesh->MapGlobalY)}; + + // The size of the mapped region + adios2::Dims count = {static_cast(mesh->MapCountX), + static_cast(mesh->MapCountY)}; + + // Where the actual data starts in data pointer (to exclude ghost cells) + adios2::Dims memStart = {static_cast(mesh->MapLocalX), + static_cast(mesh->MapLocalY)}; + + // The actual size of data pointer in memory (including ghost cells) + adios2::Dims memCount = {static_cast(value.getNx()), + static_cast(value.getNy())}; + + adios2::Variable var = stream.GetArrayVariable(varname, shape); + var.SetSelection({start, count}); + var.SetMemorySelection({memStart, memCount}); + stream.engine.Put(var, &value(0, 0)); +} + +template <> +void ADIOSPutVarVisitor::operator()(const Field3D& value) { + // Get the mesh that describes how local data relates to global arrays + auto mesh = value.getMesh(); + + // The global size of this array includes boundary cells but not communication guard cells. + // In general this array will be sparse because it may have gaps. + adios2::Dims shape = {static_cast(mesh->GlobalNx), + static_cast(mesh->GlobalNy), + static_cast(mesh->GlobalNz)}; + + // Offset of this processor's data into the global array + adios2::Dims start = {static_cast(mesh->MapGlobalX), + static_cast(mesh->MapGlobalY), + static_cast(mesh->MapGlobalZ)}; + + // The size of the mapped region + adios2::Dims count = {static_cast(mesh->MapCountX), + static_cast(mesh->MapCountY), + static_cast(mesh->MapCountZ)}; + + // Where the actual data starts in data pointer (to exclude ghost cells) + adios2::Dims memStart = {static_cast(mesh->MapLocalX), + static_cast(mesh->MapLocalY), + static_cast(mesh->MapLocalZ)}; + + // The actual size of data pointer in memory (including ghost cells) + adios2::Dims memCount = {static_cast(value.getNx()), + static_cast(value.getNy()), + static_cast(value.getNz())}; + + adios2::Variable var = stream.GetArrayVariable(varname, shape); + var.SetSelection({start, count}); + var.SetMemorySelection({memStart, memCount}); + stream.engine.Put(var, &value(0, 0, 0)); +} + +template <> +void ADIOSPutVarVisitor::operator()(const FieldPerp& value) { + // Get the mesh that describes how local data relates to global arrays + auto mesh = value.getMesh(); + + // The global size of this array includes boundary cells but not communication guard cells. + // In general this array will be sparse because it may have gaps. + adios2::Dims shape = {static_cast(mesh->GlobalNx), + static_cast(mesh->GlobalNz)}; + + // Offset of this processor's data into the global array + adios2::Dims start = {static_cast(mesh->MapGlobalX), + static_cast(mesh->MapGlobalZ)}; + + // The size of the mapped region + adios2::Dims count = {static_cast(mesh->MapCountX), + static_cast(mesh->MapCountZ)}; + + // Where the actual data starts in data pointer (to exclude ghost cells) + adios2::Dims memStart = {static_cast(mesh->MapLocalX), + static_cast(mesh->MapLocalZ)}; + + // The actual size of data pointer in memory (including ghost cells) + adios2::Dims memCount = {static_cast(value.getNx()), + static_cast(value.getNz())}; + + adios2::Variable var = stream.GetArrayVariable(varname, shape); + var.SetSelection({start, count}); + var.SetMemorySelection({memStart, memCount}); + stream.engine.Put(var, &value(0, 0)); +} + +template <> +void ADIOSPutVarVisitor::operator()>(const Array& value) { + // Pointer to data. Assumed to be contiguous array + adios2::Dims shape = {(size_t)BoutComm::size(), (size_t)value.size()}; + adios2::Dims start = {(size_t)BoutComm::rank(), 0}; + adios2::Dims count = {1, shape[1]}; + adios2::Variable var = stream.GetArrayVariable(varname, shape); + var.SetSelection({start, count}); + stream.engine.Put(var, value.begin()); +} + +template <> +void ADIOSPutVarVisitor::operator()>(const Matrix& value) { + // Pointer to data. Assumed to be contiguous array + auto s = value.shape(); + adios2::Dims shape = {(size_t)BoutComm::size(), (size_t)std::get<0>(s), + (size_t)std::get<1>(s)}; + adios2::Dims start = {(size_t)BoutComm::rank(), 0, 0}; + adios2::Dims count = {1, shape[1], shape[2]}; + adios2::Variable var = stream.GetArrayVariable(varname, shape); + var.SetSelection({start, count}); + stream.engine.Put(var, value.begin()); +} + +template <> +void ADIOSPutVarVisitor::operator()>(const Tensor& value) { + // Pointer to data. Assumed to be contiguous array + auto s = value.shape(); + adios2::Dims shape = {(size_t)BoutComm::size(), (size_t)std::get<0>(s), + (size_t)std::get<1>(s), (size_t)std::get<2>(s)}; + adios2::Dims start = {(size_t)BoutComm::rank(), 0, 0, 0}; + adios2::Dims count = {1, shape[1], shape[2], shape[3]}; + adios2::Variable var = stream.GetArrayVariable(varname, shape); + var.SetSelection({start, count}); + stream.engine.Put(var, value.begin()); +} + +/// Visit a variant type, and put the data into a NcVar +struct ADIOSPutAttVisitor { + ADIOSPutAttVisitor(const std::string& varname, const std::string& attrname, + ADIOSStream& stream) + : varname(varname), attrname(attrname), stream(stream) {} + template + void operator()(const T& value) { + stream.io.DefineAttribute(attrname, value, varname, "/", false); + } + +private: + const std::string& varname; + const std::string& attrname; + ADIOSStream& stream; +}; + +template <> +void ADIOSPutAttVisitor::operator()(const bool& value) { + stream.io.DefineAttribute(attrname, (int)value, varname, "/", false); +} + +void writeGroup(const Options& options, ADIOSStream& stream, const std::string& groupname, + const std::string& time_dimension) { + + for (const auto& childpair : options.getChildren()) { + const auto& name = childpair.first; + const auto& child = childpair.second; + + if (child.isSection()) { + TRACE("Writing group '{:s}'", name); + writeGroup(child, stream, name, time_dimension); + continue; + } + + if (child.isValue()) { + try { + auto time_it = child.attributes.find("time_dimension"); + if (time_it == child.attributes.end()) { + if (stream.adiosStep > 0) { + // we should only write the non-varying values in the first step + continue; + } + } else { + // Has a time dimension + + const auto& time_name = bout::utils::get(time_it->second); + + // Only write time-varying values that match current time + // dimension being written + if (time_name != time_dimension) { + continue; + } + } + + // Write the variable + // Note: ADIOS2 uses '/' to as a group separator; BOUT++ uses ':' + std::string varname = groupname.empty() ? name : groupname + "/" + name; + bout::utils::visit(ADIOSPutVarVisitor(varname, stream), child.value); + + // Write attributes + if (!BoutComm::rank()) { + for (const auto& attribute : child.attributes) { + const std::string& att_name = attribute.first; + const auto& att = attribute.second; + + bout::utils::visit(ADIOSPutAttVisitor(varname, att_name, stream), att); + } + } + + } catch (const std::exception& e) { + throw BoutException("Error while writing value '{:s}' : {:s}", name, e.what()); + } + } + } +} + +/// Write options to file +void OptionsADIOS::write(const Options& options, const std::string& time_dim) { + Timer timer("io"); + + // ADIOSStream is just a BOUT++ object, it does not create anything inside ADIOS + ADIOSStream& stream = ADIOSStream::ADIOSGetStream(filename); + + // Need to have an adios2::IO object first, which can only be created once. + if (!stream.io) { + ADIOSPtr adiosp = GetADIOSPtr(); + std::string ioname = "write_" + filename; + try { + stream.io = adiosp->AtIO(ioname); + } catch (const std::invalid_argument& e) { + stream.io = adiosp->DeclareIO(ioname); + stream.io.SetEngine("BP5"); + } + } + + /* Open file once and keep it open, close in stream desctructor + or close after writing if singleWriteFile == true + */ + if (!stream.engine) { + adios2::Mode amode = + (file_mode == FileMode::append ? adios2::Mode::Append : adios2::Mode::Write); + stream.engine = stream.io.Open(filename, amode); + if (!stream.engine) { + throw BoutException("Could not open ADIOS file '{:s}' for writing", filename); + } + } + + /* Multiple write() calls allowed in a single adios step to output multiple + Options objects in the same step. verifyTimesteps() will indicate the + completion of the step (and adios will publish the step). + */ + if (!stream.isInStep) { + stream.engine.BeginStep(); + stream.isInStep = true; + stream.adiosStep = stream.engine.CurrentStep(); + } + + writeGroup(options, stream, "", time_dim); + + /* In singleWriteFile mode, we complete the step and close the file */ + if (singleWriteFile) { + stream.engine.EndStep(); + stream.engine.Close(); + } +} + +} // namespace bout + +#endif // BOUT_HAS_ADIOS2 diff --git a/src/sys/options/options_adios.hxx b/src/sys/options/options_adios.hxx new file mode 100644 index 0000000000..a942e6fed9 --- /dev/null +++ b/src/sys/options/options_adios.hxx @@ -0,0 +1,83 @@ + +#pragma once + +#ifndef OPTIONS_ADIOS_H +#define OPTIONS_ADIOS_H + +#include "bout/build_config.hxx" +#include "bout/options.hxx" +#include "bout/options_io.hxx" + +#if !BOUT_HAS_ADIOS2 + +namespace { +bout::RegisterUnavailableOptionsIO + registerunavailableoptionsadios("adios", "BOUT++ was not configured with ADIOS2"); +} + +#else + +#include +#include + +namespace bout { + +/// Forward declare ADIOS file type so we don't need to depend +/// directly on ADIOS +struct ADIOSStream; + +class OptionsADIOS : public OptionsIO { +public: + // Constructors need to be defined in implementation due to forward + // declaration of ADIOSStream + OptionsADIOS() = delete; + + /// Create an OptionsADIOS + /// + /// Options: + /// - "file" The name of the file + /// If not set then "path" and "prefix" must be set, + /// and file is set to {path}/{prefix}.bp + /// - "append" + /// - "singleWriteFile" + OptionsADIOS(Options& options); + + OptionsADIOS(const OptionsADIOS&) = delete; + OptionsADIOS(OptionsADIOS&&) noexcept = default; + ~OptionsADIOS() = default; + + OptionsADIOS& operator=(const OptionsADIOS&) = delete; + OptionsADIOS& operator=(OptionsADIOS&&) noexcept = default; + + /// Read options from file + Options read() override; + + /// Write options to file + void write(const Options& options, const std::string& time_dim) override; + + /// Check that all variables with the same time dimension have the + /// same size in that dimension. Throws BoutException if there are + /// any differences, otherwise is silent + void verifyTimesteps() const override; + +private: + enum class FileMode { + replace, ///< Overwrite file when writing + append ///< Append to file when writing + }; + + /// Name of the file on disk + std::string filename; + /// How to open the file for writing + FileMode file_mode{FileMode::replace}; + bool singleWriteFile = false; +}; + +namespace { +RegisterOptionsIO registeroptionsadios("adios"); +} + +} // namespace bout + +#endif // BOUT_HAS_ADIOS2 +#endif // OPTIONS_ADIOS_H diff --git a/src/sys/options/options_ini.cxx b/src/sys/options/options_ini.cxx index a1e9bcaeb1..d1889f993b 100644 --- a/src/sys/options/options_ini.cxx +++ b/src/sys/options/options_ini.cxx @@ -189,7 +189,7 @@ void OptionINI::parse(const string& buffer, string& key, string& value) { // Just set a flag to true // e.g. "restart" or "append" on command line key = buffer; - value = string("TRUE"); + value = string("true"); return; } diff --git a/src/sys/options/options_ini.hxx b/src/sys/options/options_ini.hxx index d06a700f09..092ed9320a 100644 --- a/src/sys/options/options_ini.hxx +++ b/src/sys/options/options_ini.hxx @@ -33,8 +33,8 @@ class OptionINI; -#ifndef __OPTIONS_INI_H__ -#define __OPTIONS_INI_H__ +#ifndef BOUT_OPTIONS_INI_H +#define BOUT_OPTIONS_INI_H #include "optionparser.hxx" @@ -59,4 +59,4 @@ private: std::string getNextLine(std::ifstream& fin); }; -#endif // __OPTIONS_INI_H__ +#endif // BOUT_OPTIONS_INI_H diff --git a/src/sys/options/options_io.cxx b/src/sys/options/options_io.cxx new file mode 100644 index 0000000000..6717b6b07d --- /dev/null +++ b/src/sys/options/options_io.cxx @@ -0,0 +1,58 @@ +#include "bout/options_io.hxx" +#include "bout/bout.hxx" +#include "bout/globals.hxx" +#include "bout/mesh.hxx" + +#include "options_adios.hxx" +#include "options_netcdf.hxx" + +namespace bout { +std::unique_ptr OptionsIO::create(const std::string& file) { + return OptionsIOFactory::getInstance().createFile(file); +} + +std::unique_ptr OptionsIO::create(Options& config) { + auto& factory = OptionsIOFactory::getInstance(); + return factory.create(factory.getType(&config), config); +} + +OptionsIOFactory::ReturnType OptionsIOFactory::createRestart(Options* optionsptr) const { + Options& options = optionsptr ? *optionsptr : Options::root()["restart_files"]; + + // Set defaults + options["path"].overrideDefault( + Options::root()["datadir"].withDefault("data")); + options["prefix"].overrideDefault("BOUT.restart"); + options["append"].overrideDefault(false); + options["singleWriteFile"].overrideDefault(true); + return create(getType(&options), options); +} + +OptionsIOFactory::ReturnType OptionsIOFactory::createOutput(Options* optionsptr) const { + Options& options = optionsptr ? *optionsptr : Options::root()["output"]; + + // Set defaults + options["path"].overrideDefault( + Options::root()["datadir"].withDefault("data")); + options["prefix"].overrideDefault("BOUT.dmp"); + options["append"].overrideDefault(Options::root()["append"] + .doc("Add output data to existing (dump) files?") + .withDefault(false)); + return create(getType(&options), options); +} + +OptionsIOFactory::ReturnType OptionsIOFactory::createFile(const std::string& file) const { + Options options{{"file", file}}; + return create(getDefaultType(), options); +} + +void writeDefaultOutputFile(Options& data) { + // Add BOUT++ version and flags + bout::experimental::addBuildFlagsToOptions(data); + // Add mesh information + bout::globals::mesh->outputVars(data); + // Write to the default output file + OptionsIOFactory::getInstance().createOutput()->write(data); +} + +} // namespace bout diff --git a/src/sys/options/options_netcdf.cxx b/src/sys/options/options_netcdf.cxx index d7ceeaea60..65fbca14c0 100644 --- a/src/sys/options/options_netcdf.cxx +++ b/src/sys/options/options_netcdf.cxx @@ -2,7 +2,7 @@ #if BOUT_HAS_NETCDF && !BOUT_HAS_LEGACY_NETCDF -#include "bout/options_netcdf.hxx" +#include "options_netcdf.hxx" #include "bout/bout.hxx" #include "bout/globals.hxx" @@ -196,8 +196,7 @@ NcType NcTypeVisitor::operator()(const double& UNUSED(t)) { } template <> -MAYBE_UNUSED() -NcType NcTypeVisitor::operator()(const float& UNUSED(t)) { +[[maybe_unused]] NcType NcTypeVisitor::operator()(const float& UNUSED(t)) { return ncFloat; } @@ -403,8 +402,7 @@ void NcPutAttVisitor::operator()(const double& value) { var.putAtt(name, ncDouble, value); } template <> -MAYBE_UNUSED() -void NcPutAttVisitor::operator()(const float& value) { +[[maybe_unused]] void NcPutAttVisitor::operator()(const float& value) { var.putAtt(name, ncFloat, value); } template <> @@ -643,14 +641,19 @@ std::vector verifyTimesteps(const NcGroup& group) { namespace bout { -OptionsNetCDF::OptionsNetCDF() : data_file(nullptr) {} - -OptionsNetCDF::OptionsNetCDF(std::string filename, FileMode mode) - : filename(std::move(filename)), file_mode(mode), data_file(nullptr) {} +OptionsNetCDF::OptionsNetCDF(Options& options) : OptionsIO(options) { + if (options["file"].doc("File name. Defaults to /..nc").isSet()) { + filename = options["file"].as(); + } else { + // Both path and prefix must be set + filename = fmt::format("{}/{}.{}.nc", options["path"].as(), + options["prefix"].as(), BoutComm::rank()); + } -OptionsNetCDF::~OptionsNetCDF() = default; -OptionsNetCDF::OptionsNetCDF(OptionsNetCDF&&) noexcept = default; -OptionsNetCDF& OptionsNetCDF::operator=(OptionsNetCDF&&) noexcept = default; + file_mode = (options["append"].doc("Append to existing file?").withDefault(false)) + ? FileMode::append + : FileMode::replace; +} void OptionsNetCDF::verifyTimesteps() const { NcFile dataFile(filename, NcFile::read); @@ -699,41 +702,6 @@ void OptionsNetCDF::write(const Options& options, const std::string& time_dim) { data_file->sync(); } -std::string getRestartDirectoryName(Options& options) { - if (options["restartdir"].isSet()) { - // Solver-specific restart directory - return options["restartdir"].withDefault("data"); - } - // Use the root data directory - return options["datadir"].withDefault("data"); -} - -std::string getRestartFilename(Options& options) { - return getRestartFilename(options, BoutComm::rank()); -} - -std::string getRestartFilename(Options& options, int rank) { - return fmt::format("{}/BOUT.restart.{}.nc", bout::getRestartDirectoryName(options), - rank); -} - -std::string getOutputFilename(Options& options) { - return getOutputFilename(options, BoutComm::rank()); -} - -std::string getOutputFilename(Options& options, int rank) { - return fmt::format("{}/BOUT.dmp.{}.nc", - options["datadir"].withDefault("data"), rank); -} - -void writeDefaultOutputFile() { writeDefaultOutputFile(Options::root()); } - -void writeDefaultOutputFile(Options& options) { - bout::experimental::addBuildFlagsToOptions(options); - bout::globals::mesh->outputVars(options); - OptionsNetCDF(getOutputFilename(Options::root())).write(options); -} - } // namespace bout #endif // BOUT_HAS_NETCDF diff --git a/src/sys/options/options_netcdf.hxx b/src/sys/options/options_netcdf.hxx new file mode 100644 index 0000000000..8f195c9d92 --- /dev/null +++ b/src/sys/options/options_netcdf.hxx @@ -0,0 +1,84 @@ + +#pragma once + +#ifndef OPTIONS_NETCDF_H +#define OPTIONS_NETCDF_H + +#include "bout/build_config.hxx" + +#include "bout/options.hxx" +#include "bout/options_io.hxx" + +#if !BOUT_HAS_NETCDF || BOUT_HAS_LEGACY_NETCDF + +namespace { +RegisterUnavailableOptionsIO + registerunavailableoptionsnetcdf("netcdf", "BOUT++ was not configured with NetCDF"); +} + +#else + +#include +#include +#include + +namespace bout { + +class OptionsNetCDF : public OptionsIO { +public: + // Constructors need to be defined in implementation due to forward + // declaration of NcFile + OptionsNetCDF() = delete; + + /// Create an OptionsNetCDF + /// + /// Options: + /// - "file" The name of the file + /// If not set then "path" and "prefix" options must be set, + /// and file is set to {path}/{prefix}.{rank}.nc + /// - "append" File mode, default is false + OptionsNetCDF(Options& options); + + ~OptionsNetCDF() {} + + OptionsNetCDF(const OptionsNetCDF&) = delete; + OptionsNetCDF(OptionsNetCDF&&) noexcept = default; + OptionsNetCDF& operator=(const OptionsNetCDF&) = delete; + OptionsNetCDF& operator=(OptionsNetCDF&&) noexcept = default; + + /// Read options from file + Options read(); + + /// Write options to file + void write(const Options& options) { write(options, "t"); } + void write(const Options& options, const std::string& time_dim); + + /// Check that all variables with the same time dimension have the + /// same size in that dimension. Throws BoutException if there are + /// any differences, otherwise is silent + void verifyTimesteps() const; + +private: + enum class FileMode { + replace, ///< Overwrite file when writing + append ///< Append to file when writing + }; + + /// Pointer to netCDF file so we don't introduce direct dependence + std::unique_ptr data_file = nullptr; + + /// Name of the file on disk + std::string filename; + /// How to open the file for writing + FileMode file_mode{FileMode::replace}; +}; + +namespace { +RegisterOptionsIO registeroptionsnetcdf("netcdf"); +} + +} // namespace bout + +#endif + +#endif // OPTIONS_NETCDF_H diff --git a/src/sys/petsclib.cxx b/src/sys/petsclib.cxx index b99c51320c..f1cf1a9d1b 100644 --- a/src/sys/petsclib.cxx +++ b/src/sys/petsclib.cxx @@ -1,25 +1,64 @@ -#include "bout/build_config.hxx" +#include "bout/build_defines.hxx" #if BOUT_HAS_PETSC #include "bout/boutcomm.hxx" +#include "bout/boutexception.hxx" #include "bout/openmpwrap.hxx" #include "bout/options.hxx" -#include -#include +#include "bout/output.hxx" +#include "bout/petsclib.hxx" -#include "petscsnes.h" +#include +#include +#include +#include +#include +#include +#include -// Define all the static member variables -int PetscLib::count = 0; -char PetscLib::help[] = "BOUT++: Uses finite difference methods to solve plasma fluid " - "problems in curvilinear coordinates"; -int* PetscLib::pargc = nullptr; -char*** PetscLib::pargv = nullptr; -PetscLogEvent PetscLib::USER_EVENT = 0; +#include + +namespace { +constexpr const char* PetscLibHelp = + "BOUT++: Uses finite difference methods to solve plasma fluid " + "problems in curvilinear coordinates"; + +void setPetscOptions(Options& options, const std::string& prefix) { + // Pass all options in the section to PETSc + for (const auto& child : options.getChildren()) { + if (not child.second.isValue()) { + throw BoutException("Found subsection {} in {} when reading PETSc options - only " + "values are allowed in the PETSc options, not subsections", + child.first, options.str()); + } + + // Note, option names in the input file don't start with "-", but need to be passed + // to PETSc with "-" prepended + auto petsc_option_name = "-" + prefix + child.first; + + auto str_value = child.second.as(); + // "true" is the value given to an option with no value, when read from BOUT.inp. Also + // when nullptr is passed to PetscOptionsSetValue for a boolean option, it defaults to + // true so we should always be OK passing nullptr for null or "true". + const char* value = str_value == "true" ? nullptr : str_value.c_str(); + +#if PETSC_VERSION_GE(3, 7, 0) + const auto ierr = PetscOptionsSetValue(nullptr, petsc_option_name.c_str(), value); +#else + // no PetscOptions as first argument + const auto ierr = PetscOptionsSetValue(petsc_option_name.c_str(), value); +#endif + if (ierr != 0) { + throw BoutException("PetscOptionsSetValue returned error code {} when setting {}", + ierr, petsc_option_name); + } + } +} +} // namespace PetscLib::PetscLib(Options* opt) { - BOUT_OMP(critical(PetscLib)) + BOUT_OMP_SAFE(critical(PetscLib)) { if (count == 0) { // Initialise PETSc @@ -31,7 +70,7 @@ PetscLib::PetscLib(Options* opt) { output << "Initialising PETSc\n"; PETSC_COMM_WORLD = BoutComm::getInstance()->getComm(); - PetscInitialize(pargc, pargv, nullptr, help); + PetscInitialize(pargc, pargv, nullptr, PetscLibHelp); PetscPopSignalHandler(); PetscLogEventRegister("Total BOUT++", 0, &USER_EVENT); @@ -56,7 +95,7 @@ PetscLib::PetscLib(Options* opt) { } PetscLib::~PetscLib() { - BOUT_OMP(critical(PetscLib)) + BOUT_OMP_SAFE(critical(PetscLib)) { count--; if (count == 0) { @@ -81,7 +120,7 @@ void PetscLib::setOptionsFromInputFile(SNES& snes) { } void PetscLib::cleanup() { - BOUT_OMP(critical(PetscLib)) + BOUT_OMP_SAFE(critical(PetscLib)) { if (count > 0) { output << "Finalising PETSc. Warning: Instances of PetscLib still exist.\n"; @@ -93,43 +132,11 @@ void PetscLib::cleanup() { } } -void PetscLib::setPetscOptions(Options& options, const std::string& prefix) { - // Pass all options in the section to PETSc - for (auto& i : options.getChildren()) { - if (not i.second.isValue()) { - throw BoutException("Found subsection {} in {} when reading PETSc options - only " - "values are allowed in the PETSc options, not subsections", - i.first, options.str()); - } - - // Note, option names in the input file don't start with "-", but need to be passed - // to PETSc with "-" prepended - auto petsc_option_name = "-" + prefix + i.first; - - auto str_value = i.second.as(); - // "true" is the value given to an option with no value, when read from BOUT.inp. Also - // when nullptr is passed to PetscOptionsSetValue for a boolean option, it defaults to - // true so we should always be OK passing nullptr for null or "true". - const char* value = str_value == "true" ? nullptr : str_value.c_str(); - -#if PETSC_VERSION_GE(3, 7, 0) - const auto ierr = PetscOptionsSetValue(nullptr, petsc_option_name.c_str(), value); -#else - // no PetscOptions as first argument - const auto ierr = PetscOptionsSetValue(petsc_option_name.c_str(), value); -#endif - if (ierr) { - throw BoutException("PetscOptionsSetValue returned error code {} when setting {}", - ierr, petsc_option_name); - } - } -} - BoutException PetscLib::SNESFailure(SNES& snes) { - SNESConvergedReason reason; + SNESConvergedReason reason = SNES_CONVERGED_ITERATING; BOUT_DO_PETSC(SNESGetConvergedReason(snes, &reason)); #if PETSC_VERSION_GE(3, 15, 0) - const char* message; + const char* message{nullptr}; BOUT_DO_PETSC(SNESGetConvergedReasonString(snes, &message)); #else const char* message{""}; diff --git a/tests/MMS/GBS/gbs.hxx b/tests/MMS/GBS/gbs.hxx index e711e3ea83..468a5e579c 100644 --- a/tests/MMS/GBS/gbs.hxx +++ b/tests/MMS/GBS/gbs.hxx @@ -1,8 +1,8 @@ class GBS; -#ifndef __GBS_H__ -#define __GBS_H__ +#ifndef BOUT_GBS_H +#define BOUT_GBS_H #include @@ -96,4 +96,4 @@ private: std::unique_ptr aparSolver{nullptr}; }; -#endif // __GBS_H__ +#endif // BOUT_GBS_H diff --git a/tests/MMS/diffusion2/runtest b/tests/MMS/diffusion2/runtest index d915018d8d..6039c6faa6 100755 --- a/tests/MMS/diffusion2/runtest +++ b/tests/MMS/diffusion2/runtest @@ -27,7 +27,7 @@ build_and_log("MMS diffusion test") inputs = [ ("X", ["mesh:nx"]), ("Y", ["mesh:ny"]), - ("Z", ["MZ"]) # , + ("Z", ["MZ"]), # , # ("XYZ", ["mesh:nx", "mesh:ny", "MZ"]) ] diff --git a/tests/MMS/spatial/fci/data/BOUT.inp b/tests/MMS/spatial/fci/data/BOUT.inp index 5f377bbb56..802f70f99b 100644 --- a/tests/MMS/spatial/fci/data/BOUT.inp +++ b/tests/MMS/spatial/fci/data/BOUT.inp @@ -5,6 +5,7 @@ input_field = sin(y - 2*z) + sin(y - z) solution = (6.28318530717959*(0.01*x + 0.045)*(-2*cos(y - 2*z) - cos(y - z)) + 0.628318530717959*cos(y - 2*z) + 0.628318530717959*cos(y - z))/sqrt((0.01*x + 0.045)^2 + 1.0) MXG = 1 +MYG = 1 NXPE = 1 [mesh] diff --git a/tests/MMS/spatial/fci/fci_mms.cxx b/tests/MMS/spatial/fci/fci_mms.cxx index 5a2599368e..18405a7f88 100644 --- a/tests/MMS/spatial/fci/fci_mms.cxx +++ b/tests/MMS/spatial/fci/fci_mms.cxx @@ -17,6 +17,8 @@ int main(int argc, char** argv) { Field3D error{result - solution}; Options dump; + // Add mesh geometry variables + mesh->outputVars(dump); dump["l_2"] = sqrt(mean(SQ(error), true, "RGN_NOBNDRY")); dump["l_inf"] = max(abs(error), true, "RGN_NOBNDRY"); diff --git a/tests/MMS/spatial/fci/mms.py b/tests/MMS/spatial/fci/mms.py index 806441b330..1e71135c90 100755 --- a/tests/MMS/spatial/fci/mms.py +++ b/tests/MMS/spatial/fci/mms.py @@ -3,9 +3,6 @@ # Generate manufactured solution and sources for FCI test # -from __future__ import division -from __future__ import print_function - from boutdata.mms import * from sympy import sin, cos, sqrt diff --git a/tests/MMS/spatial/fci/runtest b/tests/MMS/spatial/fci/runtest index 3db54a3870..204a9cc271 100755 --- a/tests/MMS/spatial/fci/runtest +++ b/tests/MMS/spatial/fci/runtest @@ -27,7 +27,7 @@ nx = 3 # Not changed for these tests nlist = [8, 16, 32, 64, 128] # Number of parallel slices (in each direction) -nslices = [1, 2] +nslices = [1] directory = "data" @@ -164,7 +164,7 @@ if False: dx, error_inf[nslice], "--", - label="{} $l_\inf$".format(method_orders[nslice]["name"]), + label="{} $l_\\inf$".format(method_orders[nslice]["name"]), ) ax.legend(loc="upper left") ax.grid() diff --git a/tests/MMS/time/time.cxx b/tests/MMS/time/time.cxx index 346662a8e3..17e1f547ab 100644 --- a/tests/MMS/time/time.cxx +++ b/tests/MMS/time/time.cxx @@ -10,7 +10,7 @@ class TimeTest : public PhysicsModel { public: - int init(MAYBE_UNUSED(bool restart)) { + int init([[maybe_unused]] bool restart) override { solver->add(f, "f"); // Solve a single 3D field setSplitOperator(); @@ -18,16 +18,16 @@ class TimeTest : public PhysicsModel { return 0; } - int rhs(MAYBE_UNUSED(BoutReal time)) { + int rhs([[maybe_unused]] BoutReal time) override { ddt(f) = f; return 0; } - int convective(MAYBE_UNUSED(BoutReal time)) { + int convective([[maybe_unused]] BoutReal time) { ddt(f) = 0.5 * f; return 0; } - int diffusive(MAYBE_UNUSED(BoutReal time)) { + int diffusive([[maybe_unused]] BoutReal time) { ddt(f) = 0.5 * f; return 0; } diff --git a/tests/integrated/CMakeLists.txt b/tests/integrated/CMakeLists.txt index 8dd892ebad..ef173db7df 100644 --- a/tests/integrated/CMakeLists.txt +++ b/tests/integrated/CMakeLists.txt @@ -11,6 +11,7 @@ add_subdirectory(test-datafilefacade) add_subdirectory(test-drift-instability) add_subdirectory(test-drift-instability-staggered) add_subdirectory(test-fieldgroupComm) +add_subdirectory(test-fci-boundary) add_subdirectory(test-griddata) add_subdirectory(test-griddata-yboundary-guards) add_subdirectory(test-gyro) @@ -30,6 +31,7 @@ add_subdirectory(test-laplacexz) add_subdirectory(test-multigrid_laplace) add_subdirectory(test-naulin-laplace) add_subdirectory(test-options-netcdf) +add_subdirectory(test-options-adios) add_subdirectory(test-petsc_laplace) add_subdirectory(test-petsc_laplace_MAST-grid) add_subdirectory(test-restart-io) diff --git a/tests/integrated/test-beuler/test_beuler.cxx b/tests/integrated/test-beuler/test_beuler.cxx index cfdae89eb2..5a080767dd 100644 --- a/tests/integrated/test-beuler/test_beuler.cxx +++ b/tests/integrated/test-beuler/test_beuler.cxx @@ -41,7 +41,6 @@ class TestSolver : public PhysicsModel { }; int main(int argc, char** argv) { - // Absolute tolerance for difference between the actual value and the // expected value constexpr BoutReal tolerance = 1.e-5; @@ -87,8 +86,6 @@ int main(int argc, char** argv) { solver->solve(); - BoutFinalise(false); - if (model.check_solution(tolerance)) { output_test << " PASSED\n"; return 0; diff --git a/tests/integrated/test-boutpp/collect-staggered/data/BOUT.inp b/tests/integrated/test-boutpp/collect-staggered/data/BOUT.inp index 6dc68a7e8b..cb1d1ec7f6 100644 --- a/tests/integrated/test-boutpp/collect-staggered/data/BOUT.inp +++ b/tests/integrated/test-boutpp/collect-staggered/data/BOUT.inp @@ -2,7 +2,7 @@ nout = 10 timestep = 0.1 [mesh] -staggergrids = True +staggergrids = true n = 1 nx = n+2*MXG ny = 16 diff --git a/tests/integrated/test-boutpp/collect/input/BOUT.inp b/tests/integrated/test-boutpp/collect/input/BOUT.inp index a390bb1891..cad2f17c52 100644 --- a/tests/integrated/test-boutpp/collect/input/BOUT.inp +++ b/tests/integrated/test-boutpp/collect/input/BOUT.inp @@ -5,7 +5,7 @@ MXG = 2 MYG = 2 [mesh] -staggergrids = True +staggergrids = true n = 1 nx = n+2*MXG ny = n diff --git a/tests/integrated/test-boutpp/legacy-model/data/BOUT.inp b/tests/integrated/test-boutpp/legacy-model/data/BOUT.inp index c6dd2fd761..b6b44502f6 100644 --- a/tests/integrated/test-boutpp/legacy-model/data/BOUT.inp +++ b/tests/integrated/test-boutpp/legacy-model/data/BOUT.inp @@ -2,7 +2,7 @@ nout = 10 timestep = 0.1 [mesh] -staggergrids = True +staggergrids = true n = 1 nx = n+2*MXG ny = n diff --git a/tests/integrated/test-boutpp/mms-ddz/data/BOUT.inp b/tests/integrated/test-boutpp/mms-ddz/data/BOUT.inp index a390bb1891..cad2f17c52 100644 --- a/tests/integrated/test-boutpp/mms-ddz/data/BOUT.inp +++ b/tests/integrated/test-boutpp/mms-ddz/data/BOUT.inp @@ -5,7 +5,7 @@ MXG = 2 MYG = 2 [mesh] -staggergrids = True +staggergrids = true n = 1 nx = n+2*MXG ny = n diff --git a/tests/integrated/test-fci-boundary/CMakeLists.txt b/tests/integrated/test-fci-boundary/CMakeLists.txt new file mode 100644 index 0000000000..bf25cd7c57 --- /dev/null +++ b/tests/integrated/test-fci-boundary/CMakeLists.txt @@ -0,0 +1,22 @@ +bout_add_mms_test(test-fci-boundary + SOURCES get_par_bndry.cxx + USE_RUNTEST + USE_DATA_BOUT_INP + REQUIRES zoidberg_FOUND + PROCESSORS 1 + ) + +if (zoidberg_FOUND) + set(gridfile ${CMAKE_CURRENT_BINARY_DIR}/grid.fci.nc) + add_custom_command(OUTPUT ${gridfile} + COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${BOUT_PYTHONPATH}:$ENV{PYTHONPATH} ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/grid.py ${gridfile} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../../../tools/pylib/boutconfig/__init__.py + DEPENDS grid.py + IMPLICIT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Creating test-fci-boundary grid file" + ) + add_custom_target(test-fci-boundary-grid DEPENDS ${gridfile}) + add_dependencies(test-fci-boundary + test-fci-boundary-grid) +endif() diff --git a/tests/integrated/test-fci-boundary/data/BOUT.inp b/tests/integrated/test-fci-boundary/data/BOUT.inp new file mode 100644 index 0000000000..b631f16295 --- /dev/null +++ b/tests/integrated/test-fci-boundary/data/BOUT.inp @@ -0,0 +1,20 @@ +grid = grid.fci.nc + +MXG = 1 +NXPE = 1 +MYG = 1 + +[mesh] +symmetricglobalx = true + +[mesh:ddy] +first = C2 +second = C2 + +[mesh:paralleltransform] +type = fci +y_periodic = true +z_periodic = true + +[mesh:paralleltransform:xzinterpolation] +type = lagrange4pt diff --git a/tests/integrated/test-fci-boundary/get_par_bndry.cxx b/tests/integrated/test-fci-boundary/get_par_bndry.cxx new file mode 100644 index 0000000000..ac0f5de2a6 --- /dev/null +++ b/tests/integrated/test-fci-boundary/get_par_bndry.cxx @@ -0,0 +1,34 @@ +#include "bout/bout.hxx" +#include "bout/derivs.hxx" +#include "bout/field_factory.hxx" +#include "bout/parallel_boundary_region.hxx" + +int main(int argc, char** argv) { + BoutInitialise(argc, argv); + + using bout::globals::mesh; + + std::vector fields; + fields.resize(static_cast(BoundaryParType::SIZE)); + Options dump; + for (int i = 0; i < fields.size(); i++) { + fields[i] = Field3D{0.0}; + mesh->communicate(fields[i]); + for (const auto& bndry_par : + mesh->getBoundariesPar(static_cast(i))) { + output.write("{:s} region\n", toString(static_cast(i))); + for (bndry_par->first(); !bndry_par->isDone(); bndry_par->next()) { + fields[i][bndry_par->ind()] += 1; + output.write("{:s} increment\n", toString(static_cast(i))); + } + } + output.write("{:s} done\n", toString(static_cast(i))); + + dump[fmt::format("field_{:s}", toString(static_cast(i)))] = + fields[i]; + } + + bout::writeDefaultOutputFile(dump); + + BoutFinalise(); +} diff --git a/tests/integrated/test-fci-boundary/grid.py b/tests/integrated/test-fci-boundary/grid.py new file mode 100644 index 0000000000..d544f0cdf7 --- /dev/null +++ b/tests/integrated/test-fci-boundary/grid.py @@ -0,0 +1,55 @@ +import zoidberg as zb +import numpy as np +import sys +import boutconfig as bc + + +def rotating_ellipse( + nx=68, + ny=16, + nz=128, + npoints=421, + xcentre=5.5, + I_coil=0.01, + curvilinear=True, + rectangular=False, + fname="rotating-ellipse.fci.nc", + a=0.4, + Btor=2.5, +): + yperiod = 2 * np.pi / 5.0 + field = zb.field.RotatingEllipse( + xcentre=xcentre, + I_coil=I_coil, + radius=2 * a, + yperiod=yperiod, + Btor=Btor, + ) + # Define the y locations + ycoords = np.linspace(0.0, yperiod, ny, endpoint=False) + + if rectangular: + print("Making rectangular poloidal grid") + poloidal_grid = zb.poloidal_grid.RectangularPoloidalGrid( + nx, nz, 1.0, 1.0, Rcentre=xcentre + ) + elif curvilinear: + print("Making curvilinear poloidal grid") + inner = zb.rzline.shaped_line( + R0=xcentre, a=a / 2.0, elong=0, triang=0.0, indent=0, n=npoints + ) + outer = zb.rzline.shaped_line( + R0=xcentre, a=a, elong=0, triang=0.0, indent=0, n=npoints + ) + + print("creating grid...") + poloidal_grid = zb.poloidal_grid.grid_elliptic(inner, outer, nx, nz) + + # Create the 3D grid by putting together 2D poloidal grids + grid = zb.grid.Grid(poloidal_grid, ycoords, yperiod, yperiodic=True) + maps = zb.make_maps(grid, field, quiet=True) + zb.write_maps(grid, field, maps, str(fname), metric2d=bc.isMetric2D()) + + +if __name__ == "__main__": + rotating_ellipse(fname=sys.argv[1]) diff --git a/tests/integrated/test-fci-boundary/runtest b/tests/integrated/test-fci-boundary/runtest new file mode 100755 index 0000000000..16cb4ee443 --- /dev/null +++ b/tests/integrated/test-fci-boundary/runtest @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# +# Python script to run and analyse MMS test +# + +# Cores: 2 +# only working with cmake +# requires: False +from boututils.run_wrapper import launch_safe +from boututils.datafile import DataFile +from boutdata.collect import collect as _collect + +import numpy as np + + +def collect(var): + return _collect( + var, + info=False, + path=directory, + xguards=False, + yguards=False, + ) + + +nprocs = [1] # , 2, 4] +mthread = 2 + +directory = "data" + +with DataFile("grid.fci.nc") as grid: + xfwd = grid.read("forward_xt_prime")[1:-1] + xbwd = grid.read("backward_xt_prime")[1:-1] + +nx = xfwd.shape[0] + +regions = { + "xin_fwd": xfwd < 1, + "xout_fwd": xfwd > nx, + "xin_bwd": xbwd < 1, + "xout_bwd": xbwd > nx, +} +regions = {k: v.astype(int) for k, v in regions.items()} + +# for x in "xout", "xin": +# regions[x] = np.logical_or(regions[f"{x}_fwd"], regions[f"{x}_bwd"]) +# for x in "fwd", "bwd": +# regions[x] = np.logical_or(regions[f"xin_{x}"], regions[f"xout_{x}"]) +# regions["all"] = np.logical_or(regions["xin"], regions["xout"]) +for x in "xout", "xin": + regions[x] = regions[f"{x}_fwd"] + regions[f"{x}_bwd"] +for x in "fwd", "bwd": + regions[x] = regions[f"xin_{x}"] + regions[f"xout_{x}"] +regions["all"] = regions["xin"] + regions["xout"] + +for nproc in nprocs: + cmd = "./get_par_bndry" + + # Launch using MPI + _, out = launch_safe(cmd, nproc=nproc, mthread=mthread, pipe=True) + + for k, v in regions.items(): + # Collect data + data = collect(f"field_{k}") + assert np.allclose(data, v), ( + k + " does not match", + np.sum(data), + np.sum(v), + np.max(data), + ) diff --git a/tests/integrated/test-griddata/test_griddata.cxx b/tests/integrated/test-griddata/test_griddata.cxx index 9f12d48d9d..0277f9e001 100644 --- a/tests/integrated/test-griddata/test_griddata.cxx +++ b/tests/integrated/test-griddata/test_griddata.cxx @@ -13,7 +13,7 @@ int main(int argc, char** argv) { dump["Bpxy"] = Bpxy; bout::experimental::addBuildFlagsToOptions(dump); bout::globals::mesh->outputVars(dump); - bout::OptionsNetCDF("data.nc").write(dump); + bout::OptionsIO::create("data.nc")->write(dump); BoutFinalise(); return 0; diff --git a/tests/integrated/test-interchange-instability/orig_test.idl.dat b/tests/integrated/test-interchange-instability/orig_test.idl.dat deleted file mode 100644 index 93652ca856..0000000000 Binary files a/tests/integrated/test-interchange-instability/orig_test.idl.dat and /dev/null differ diff --git a/tests/integrated/test-laplace-hypre3d/data_circular_core-sol/BOUT.inp b/tests/integrated/test-laplace-hypre3d/data_circular_core-sol/BOUT.inp index 9a6ac24fa1..46d3cb55ba 100644 --- a/tests/integrated/test-laplace-hypre3d/data_circular_core-sol/BOUT.inp +++ b/tests/integrated/test-laplace-hypre3d/data_circular_core-sol/BOUT.inp @@ -1,7 +1,7 @@ [f] #function = 0. function = mixmode(x, 1.)*mixmode(y, 2.)*mixmode(z, 3.) -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 [rhs] function = mixmode(x, 4.)*mixmode(y, 5.)*mixmode(z, 6.) @@ -17,7 +17,7 @@ function = 1. + .1*mixmode(x, 10.)*mixmode(y, 11.)*mixmode(z, 12.) [C2] #function = 0. function = .1*mixmode(x, 13.)*mixmode(y, 14.)*mixmode(z, 15.) -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 [A] function = 0. diff --git a/tests/integrated/test-laplace-hypre3d/data_circular_core/BOUT.inp b/tests/integrated/test-laplace-hypre3d/data_circular_core/BOUT.inp index eb78644f0f..be0c697d80 100644 --- a/tests/integrated/test-laplace-hypre3d/data_circular_core/BOUT.inp +++ b/tests/integrated/test-laplace-hypre3d/data_circular_core/BOUT.inp @@ -16,7 +16,7 @@ function = 1. + .1*mixmode(x, 10.)*mixmode(y, 11.)*mixmode(z, 12.) [C2] #function = 0. function = .1*mixmode(x, 13.)*mixmode(y, 14.)*mixmode(z, 15.) -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 [A] function = 0. diff --git a/tests/integrated/test-laplace-petsc3d/data_circular_core-sol/BOUT.inp b/tests/integrated/test-laplace-petsc3d/data_circular_core-sol/BOUT.inp index da1918dcc7..bc3c47eac7 100644 --- a/tests/integrated/test-laplace-petsc3d/data_circular_core-sol/BOUT.inp +++ b/tests/integrated/test-laplace-petsc3d/data_circular_core-sol/BOUT.inp @@ -17,7 +17,7 @@ function = 1. + .1*mixmode(x, 10.)*mixmode(y, 11.)*mixmode(z, 12.) [C2] #function = 0. function = .1*mixmode(x, 13.)*mixmode(y, 14.)*mixmode(z, 15.) -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 [A] function = 0.0 diff --git a/tests/integrated/test-laplace-petsc3d/data_circular_core/BOUT.inp b/tests/integrated/test-laplace-petsc3d/data_circular_core/BOUT.inp index 6474b2604b..601531de84 100644 --- a/tests/integrated/test-laplace-petsc3d/data_circular_core/BOUT.inp +++ b/tests/integrated/test-laplace-petsc3d/data_circular_core/BOUT.inp @@ -17,7 +17,7 @@ function = 1. + .1*mixmode(x, 10.)*mixmode(y, 11.)*mixmode(z, 12.) [C2] #function = 0. function = .1*mixmode(x, 13.)*mixmode(y, 14.)*mixmode(z, 15.) -bndry_par_all = parallel_neumann +bndry_par_all = parallel_neumann_o2 [A] function = 0.0 diff --git a/tests/integrated/test-laplace-petsc3d/runtest b/tests/integrated/test-laplace-petsc3d/runtest index 88f9d76c62..7b0d55f357 100755 --- a/tests/integrated/test-laplace-petsc3d/runtest +++ b/tests/integrated/test-laplace-petsc3d/runtest @@ -3,7 +3,7 @@ # requires: petsc from boutdata import collect -from boututils.run_wrapper import launch_safe, build_and_log +from boututils.run_wrapper import launch, build_and_log from sys import exit test_directories = [ @@ -18,21 +18,30 @@ tolerance = 1.0e-6 build_and_log("Laplace 3D with PETSc") success = True +errors = {} + for directory, nproc in test_directories: - command = "./test-laplace3d -d " + directory + command = f"./test-laplace3d -d {directory}" print("running on", nproc, "processors:", command) - launch_safe(command, nproc=nproc) + status, output = launch(command, nproc=nproc, pipe=True) - error_max = collect("error_max", path=directory, info=False) + if status: + print("FAILED") + print(output) + errors[directory] = "" + continue + error_max = collect("error_max", path=directory, info=False) if error_max > tolerance: - print(directory + " failed with maximum error {}".format(error_max)) - success = False - else: - print(directory + " passed with maximum error {}".format(error_max)) - -if success: - print("All passed") - exit(0) -else: + errors[directory] = error_max + +print("**********") + +if errors: + print("Some failures:") + for name, error in errors.items(): + print(f"{name}, max error: {error}") exit(1) + +print("All passed") +exit(0) diff --git a/tests/integrated/test-laplace-petsc3d/test-laplace3d.cxx b/tests/integrated/test-laplace-petsc3d/test-laplace3d.cxx index a1231a6cdf..a865f04e2f 100644 --- a/tests/integrated/test-laplace-petsc3d/test-laplace3d.cxx +++ b/tests/integrated/test-laplace-petsc3d/test-laplace3d.cxx @@ -126,6 +126,7 @@ int main(int argc, char** argv) { Field3D rhs_check = D * Laplace_perp(f) + Grad_perp(C2) * Grad_perp(f) / C1 + A * f; Field3D error = rhs_check - rhs; BoutReal error_max = max(abs(error), true); + output.write("error_max = {}\n", error_max); Options dump; dump["f"] = f; diff --git a/tests/integrated/test-laplacexy/loadmetric.hxx b/tests/integrated/test-laplacexy/loadmetric.hxx index 141269d8b8..25e55fc8e8 100644 --- a/tests/integrated/test-laplacexy/loadmetric.hxx +++ b/tests/integrated/test-laplacexy/loadmetric.hxx @@ -1,8 +1,8 @@ -#ifndef __LOADMETRIC_H__ -#define __LOADMETRIC_H__ +#ifndef BOUT_LOADMETRIC_H +#define BOUT_LOADMETRIC_H #include void LoadMetric(BoutReal Lnorm, BoutReal Bnorm); -#endif // __LOADMETRIC_H__ +#endif // BOUT_LOADMETRIC_H diff --git a/tests/integrated/test-options-adios/CMakeLists.txt b/tests/integrated/test-options-adios/CMakeLists.txt new file mode 100644 index 0000000000..cc61fabe57 --- /dev/null +++ b/tests/integrated/test-options-adios/CMakeLists.txt @@ -0,0 +1,6 @@ +bout_add_integrated_test(test-options-adios + SOURCES test-options-adios.cxx + USE_RUNTEST + USE_DATA_BOUT_INP + REQUIRES BOUT_HAS_ADIOS2 + ) diff --git a/tests/integrated/test-options-adios/data/BOUT.inp b/tests/integrated/test-options-adios/data/BOUT.inp new file mode 100644 index 0000000000..fa0f6d3681 --- /dev/null +++ b/tests/integrated/test-options-adios/data/BOUT.inp @@ -0,0 +1,6 @@ + + +[mesh] +nx = 5 +ny = 2 +nz = 2 diff --git a/tests/integrated/test-options-adios/makefile b/tests/integrated/test-options-adios/makefile new file mode 100644 index 0000000000..7dbbce8736 --- /dev/null +++ b/tests/integrated/test-options-adios/makefile @@ -0,0 +1,6 @@ + +BOUT_TOP = ../../.. + +SOURCEC = test-options-adios.cxx + +include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-options-adios/runtest b/tests/integrated/test-options-adios/runtest new file mode 100755 index 0000000000..03a83fc0ba --- /dev/null +++ b/tests/integrated/test-options-adios/runtest @@ -0,0 +1,74 @@ +#!/usr/bin/env python3 + +# Note: This test requires NCDF4, whereas on Travis NCDF is used +# requires: netcdf +# requires: adios +# requires: not legacy_netcdf + +from boututils.datafile import DataFile +from boututils.run_wrapper import build_and_log, shell, launch +from boutdata.data import BoutOptionsFile + +import math +import numpy as np + +build_and_log("options-netcdf test") +shell("rm -f test-out.ini") +shell("rm -f test-out.nc") + +# Create a NetCDF input file +with DataFile("test.nc", create=True, format="NETCDF4") as f: + f.write("int", 42) + f.write("real", 3.1415) + f.write("string", "hello") + +# run BOUT++ +launch("./test-options-adios", nproc=1, mthread=1) + +# Check the output INI file +result = BoutOptionsFile("test-out.ini") + +print(result) + +assert result["int"] == 42 +assert math.isclose(result["real"], 3.1415) +assert result["string"] == "hello" + +print("Checking saved ADIOS2 test-out file -- Not implemented") + +# Check the output NetCDF file +# with DataFile("test-out.nc") as f: +# assert f["int"] == 42 +# assert math.isclose(f["real"], 3.1415) +# assert result["string"] == "hello" + +print("Checking saved settings.ini") + +# Check the settings.ini file, coming from BOUT.inp +# which is converted to NetCDF, read in, then written again +settings = BoutOptionsFile("settings.ini") + +assert settings["mesh"]["nx"] == 5 +assert settings["mesh"]["ny"] == 2 + +print("Checking saved fields.bp -- Not implemented") + +# with DataFile("fields.nc") as f: +# assert f["f2d"].shape == (5, 6) # Field2D +# assert f["f3d"].shape == (5, 6, 2) # Field3D +# assert f["fperp"].shape == (5, 2) # FieldPerp +# assert np.allclose(f["f2d"], 1.0) +# assert np.allclose(f["f3d"], 2.0) +# assert np.allclose(f["fperp"], 3.0) + +print("Checking saved fields2.bp -- Not implemented") + +# with DataFile("fields2.nc") as f: +# assert f["f2d"].shape == (5, 6) # Field2D +# assert f["f3d"].shape == (5, 6, 2) # Field3D +# assert f["fperp"].shape == (5, 2) # FieldPerp +# assert np.allclose(f["f2d"], 1.0) +# assert np.allclose(f["f3d"], 2.0) +# assert np.allclose(f["fperp"], 3.0) + +print(" => Passed") diff --git a/tests/integrated/test-options-adios/test-options-adios.cxx b/tests/integrated/test-options-adios/test-options-adios.cxx new file mode 100644 index 0000000000..60604e1aa3 --- /dev/null +++ b/tests/integrated/test-options-adios/test-options-adios.cxx @@ -0,0 +1,111 @@ + +#include "bout/bout.hxx" + +#include "bout/options_io.hxx" +#include "bout/optionsreader.hxx" + +using bout::OptionsIO; + +int main(int argc, char** argv) { + BoutInitialise(argc, argv); + + // Read values from a NetCDF file + auto file = bout::OptionsIO::create("test.nc"); + + auto values = file->read(); + + values.printUnused(); + + // Write to an INI text file + OptionsReader* reader = OptionsReader::getInstance(); + reader->write(&values, "test-out.ini"); + + // Write to ADIOS file, by setting file type "adios" + OptionsIO::create({{"file", "test-out.bp"}, + {"type", "adios"}, + {"append", false}, + {"singleWriteFile", true}}) + ->write(values); + + /////////////////////////// + + // Write the BOUT.inp settings to ADIOS file + OptionsIO::create({{"file", "settings.bp"}, + {"type", "adios"}, + {"append", false}, + {"singleWriteFile", true}}) + ->write(Options::root()); + + // Read back in + auto settings = OptionsIO::create({{"file", "settings.bp"}, {"type", "adios"}})->read(); + + // Write to INI file + reader->write(&settings, "settings.ini"); + + /////////////////////////// + // Write fields + + Options fields; + fields["f2d"] = Field2D(1.0); + fields["f3d"] = Field3D(2.0); + fields["fperp"] = FieldPerp(3.0); + auto f = OptionsIO::create({{"file", "fields.bp"}, {"type", "adios"}}); + /* + write() for adios only buffers data but does not guarantee writing to disk + unless singleWriteFile is set to true + */ + f->write(fields); + // indicate completion of step, required to get data on disk + f->verifyTimesteps(); + + /////////////////////////// + // Read fields + + Options fields_in = + OptionsIO::create({{"file", "fields.bp"}, {"type", "adios"}})->read(); + + auto f2d = fields_in["f2d"].as(bout::globals::mesh); + auto f3d = fields_in["f3d"].as(bout::globals::mesh); + auto fperp = fields_in["fperp"].as(bout::globals::mesh); + + Options fields2; + fields2["f2d"] = f2d; + fields2["f3d"] = f3d; + fields2["fperp"] = fperp; + + // Write out again + auto f2 = OptionsIO::create({{"file", "fields2.bp"}, + {"type", "adios"}, + {"append", false}, + {"singleWriteFile", true}}); + f2->write(fields2); + + /////////////////////////// + // Time dependent values + + Options data; + data["scalar"] = 1.0; + data["scalar"].attributes["time_dimension"] = "t"; + + data["field"] = Field3D(2.0); + data["field"].attributes["time_dimension"] = "t"; + + OptionsIO::create({{"file", "time.bp"}, + {"type", "adios"}, + {"append", false}, + {"singleWriteFile", true}}) + ->write(data); + + // Update time-dependent values + data["scalar"] = 2.0; + data["field"] = Field3D(3.0); + + // Append data to file + OptionsIO::create({{"file", "time.bp"}, + {"type", "adios"}, + {"append", true}, + {"singleWriteFile", true}}) + ->write(data); + + BoutFinalise(); +}; diff --git a/tests/integrated/test-options-netcdf/test-options-netcdf.cxx b/tests/integrated/test-options-netcdf/test-options-netcdf.cxx index 01c5749972..f5daf8919c 100644 --- a/tests/integrated/test-options-netcdf/test-options-netcdf.cxx +++ b/tests/integrated/test-options-netcdf/test-options-netcdf.cxx @@ -1,18 +1,18 @@ #include "bout/bout.hxx" -#include "bout/options_netcdf.hxx" +#include "bout/options_io.hxx" #include "bout/optionsreader.hxx" -using bout::OptionsNetCDF; +using bout::OptionsIO; int main(int argc, char** argv) { BoutInitialise(argc, argv); // Read values from a NetCDF file - OptionsNetCDF file("test.nc"); + auto file = OptionsIO::create("test.nc"); - auto values = file.read(); + auto values = file->read(); values.printUnused(); @@ -21,15 +21,15 @@ int main(int argc, char** argv) { reader->write(&values, "test-out.ini"); // Write to a NetCDF file - OptionsNetCDF("test-out.nc").write(values); + OptionsIO::create("test-out.nc")->write(values); /////////////////////////// // Write the BOUT.inp settings to NetCDF file - OptionsNetCDF("settings.nc").write(Options::root()); + OptionsIO::create("settings.nc")->write(Options::root()); // Read back in - auto settings = OptionsNetCDF("settings.nc").read(); + auto settings = OptionsIO::create("settings.nc")->read(); // Write to INI file reader->write(&settings, "settings.ini"); @@ -41,12 +41,12 @@ int main(int argc, char** argv) { fields["f2d"] = Field2D(1.0); fields["f3d"] = Field3D(2.0); fields["fperp"] = FieldPerp(3.0); - OptionsNetCDF("fields.nc").write(fields); + OptionsIO::create("fields.nc")->write(fields); /////////////////////////// // Read fields - Options fields_in = OptionsNetCDF("fields.nc").read(); + Options fields_in = OptionsIO::create("fields.nc")->read(); auto f2d = fields_in["f2d"].as(bout::globals::mesh); auto f3d = fields_in["f3d"].as(bout::globals::mesh); @@ -58,7 +58,7 @@ int main(int argc, char** argv) { fields2["fperp"] = fperp; // Write out again - OptionsNetCDF("fields2.nc").write(fields2); + OptionsIO::create("fields2.nc")->write(fields2); /////////////////////////// // Time dependent values @@ -70,14 +70,14 @@ int main(int argc, char** argv) { data["field"] = Field3D(2.0); data["field"].attributes["time_dimension"] = "t"; - OptionsNetCDF("time.nc").write(data); + OptionsIO::create("time.nc")->write(data); // Update time-dependent values data["scalar"] = 2.0; data["field"] = Field3D(3.0); // Append data to file - OptionsNetCDF("time.nc", OptionsNetCDF::FileMode::append).write(data); + OptionsIO::create({{"file", "time.nc"}, {"append", true}})->write(data); BoutFinalise(); }; diff --git a/tests/integrated/test-petsc_laplace/test_petsc_laplace.cxx b/tests/integrated/test-petsc_laplace/test_petsc_laplace.cxx index bfd394194f..1e3cdde310 100644 --- a/tests/integrated/test-petsc_laplace/test_petsc_laplace.cxx +++ b/tests/integrated/test-petsc_laplace/test_petsc_laplace.cxx @@ -23,15 +23,90 @@ * **************************************************************************/ -#include -#include -// #include -#include -#include -#include +#include "bout/bout.hxx" // NOLINT +#include "bout/bout_types.hxx" +#include "bout/boutexception.hxx" +#include "bout/constants.hxx" +#include "bout/difops.hxx" +#include "bout/field2d.hxx" +#include "bout/field3d.hxx" +#include "bout/invert_laplace.hxx" +#include "bout/options.hxx" +#include "bout/options_io.hxx" +#include "bout/output.hxx" +#include "bout/traits.hxx" + +#include "fmt/core.h" +#include + #include +#include BoutReal max_error_at_ystart(const Field3D& error); +void apply_flat_boundary(Field3D& bcoef); + +template +void check_laplace(int test_num, std::string_view test_name, Laplacian& invert, + int inner_flags, int outer_flags, const T& acoef, const T& ccoef, + const T& dcoef, const U& bcoef, const Field3D& field, int ystart, + Options& dump) { + static_assert(bout::utils::is_Field_v, "check_laplace requires Field2D or Field3D"); + static_assert(bout::utils::is_Field_v, "check_laplace requires Field2D or Field3D"); + + invert.setInnerBoundaryFlags(inner_flags); + invert.setOuterBoundaryFlags(outer_flags); + invert.setCoefA(acoef); + invert.setCoefC(ccoef); + invert.setCoefD(dcoef); + + checkData(bcoef); + + Field3D sol; + Field3D error; + Field3D abs_error; + BoutReal max_error = -1; + + try { + sol = invert.solve(sliceXZ(bcoef, ystart)); + error = (field - sol) / field; + abs_error = field - sol; + max_error = max_error_at_ystart(abs(abs_error)); + } catch (BoutException& err) { + output.write("BoutException occured in invert->solve(b1): {}\n", err.what()); + } + + output.write("\nTest {}: {}\n", test_num, test_name); + output.write("Magnitude of maximum absolute error is {}\n", max_error); + + dump[fmt::format("a{}", test_num)] = acoef; + dump[fmt::format("b{}", test_num)] = bcoef; + dump[fmt::format("c{}", test_num)] = ccoef; + dump[fmt::format("d{}", test_num)] = dcoef; + dump[fmt::format("f{}", test_num)] = field; + dump[fmt::format("sol{}", test_num)] = sol; + dump[fmt::format("error{}", test_num)] = error; + dump[fmt::format("absolute_error{}", test_num)] = abs_error; + dump[fmt::format("max_error{}", test_num)] = max_error; +} + +template +Field3D forward_laplace(const Field3D& field, const T& acoef, const T& ccoef, + const T& dcoef) { + auto bcoef = + dcoef * Delp2(field) + Grad_perp(ccoef) * Grad_perp(field) / ccoef + acoef * field; + apply_flat_boundary(bcoef); + return bcoef; +} + +Field3D generate_f1(const Mesh& mesh); +Field3D generate_a1(const Mesh& mesh); +Field3D generate_c1(const Mesh& mesh); +Field3D generate_d1(const Mesh& mesh); + +Field3D generate_f5(const Mesh& mesh); +Field3D generate_a5(const Mesh& mesh); +Field3D generate_c5(const Mesh& mesh); +Field3D generate_d5(const Mesh& mesh); int main(int argc, char** argv) { @@ -42,829 +117,553 @@ int main(int argc, char** argv) { options = Options::getRoot()->getSection("petsc4th"); auto invert_4th = Laplacian::create(options); - // Solving equations of the form d*Delp2(f) + 1/c*Grad_perp(c).Grad_perp(f) + a*f = b for various f, a, c, d - Field3D f1, a1, b1, c1, d1, sol1; - BoutReal p, q; //Use to set parameters in constructing trial functions - Field3D error1, - absolute_error1; //Absolute value of relative error: abs( (f1-sol1)/f1 ) - BoutReal max_error1; //Output of test + Options dump; + // Solving equations of the form d*Delp2(f) + 1/c*Grad_perp(c).Grad_perp(f) + a*f = b for various f, a, c, d using bout::globals::mesh; // Only Neumann x-boundary conditions are implemented so far, so test functions should be Neumann in x and periodic in z. // Use Field3D's, but solver only works on FieldPerp slices, so only use 1 y-point - BoutReal nx = mesh->GlobalNx - 2 * mesh->xstart - 1; - BoutReal nz = mesh->GlobalNz; - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////// // Test 1: Gaussian x-profiles, 2nd order Krylov - p = 0.39503274; - q = 0.20974396; - f1.allocate(); - for (int jx = mesh->xstart; jx <= mesh->xend; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - f1(jx, jy, jz) = - 0. + exp(-(100. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) - - 50. - * (2. * p * exp(-100. * pow(-p, 2)) * x - + (-p * exp(-100. * pow(-p, 2)) - - (1 - p) * exp(-100. * pow(1 - p, 2))) - * pow(x, 2)) - * exp(-( - 1. - - cos(2. * PI - * (z - q)))) //make the gradients zero at both x-boundaries - ; - ASSERT0(finite(f1(jx, jy, jz))); - } - } - } - if (mesh->firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - f1(jx, jy, jz) = - 0. + exp(-(60. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) - - 50. - * (2. * p * exp(-60. * pow(-p, 2)) * x - + (-p * exp(-60. * pow(-p, 2)) - - (1 - p) * exp(-60. * pow(1 - p, 2))) - * pow(x, 2)) - * exp(-( - 1. - - cos( - 2. * PI - * (z - q)))); //make the gradients zero at both x-boundaries - ASSERT0(finite(f1(jx, jy, jz))); - } - } - } - } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - f1(jx, jy, jz) = - 0. + exp(-(60. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) - - 50. - * (2. * p * exp(-60. * pow(-p, 2)) * x - + (-p * exp(-60. * pow(-p, 2)) - - (1 - p) * exp(-60. * pow(1 - p, 2))) - * pow(x, 2)) - * exp(-( - 1. - - cos( - 2. * PI - * (z - q)))); //make the gradients zero at both x-boundaries - ASSERT0(finite(f1(jx, jy, jz))); - } - } - } - } + Field3D f_1 = generate_f1(*mesh); + Field3D a_1 = generate_a1(*mesh); + Field3D c_1 = generate_c1(*mesh); + Field3D d_1 = generate_d1(*mesh); - f1.applyBoundary("neumann"); - - p = 0.512547; - q = 0.30908712; - d1.allocate(); - for (int jx = mesh->xstart; jx <= mesh->xend; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - d1(jx, jy, jz) = - 1. + 0.2 * exp(-50. * pow(x - p, 2) / 4.) * sin(2. * PI * (z - q) * 3.); - } - } - } - if (mesh->firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - d1(jx, jy, jz) = - 1. + 0.2 * exp(-50. * pow(x - p, 2) / 4.) * sin(2. * PI * (z - q) * 3.); - // d1(jx, jy, jz) = d1(jx+1, jy, jz); - } - } - } - } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - d1(jx, jy, jz) = - 1. + 0.2 * exp(-50. * pow(x - p, 2) / 4.) * sin(2. * PI * (z - q) * 3.); - // d1(jx, jy, jz) = d1(jx-1, jy, jz); - } - } - } - } + mesh->communicate(f_1, a_1, c_1, d_1); - p = 0.18439023; - q = 0.401089473; - c1.allocate(); - for (int jx = mesh->xstart; jx <= mesh->xend; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - c1(jx, jy, jz) = - 1. + 0.15 * exp(-50. * pow(x - p, 2) * 2.) * sin(2. * PI * (z - q) * 2.); - } - } - } - if (mesh->firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - c1(jx, jy, jz) = - 1. + 0.15 * exp(-50. * pow(x - p, 2) * 2.) * sin(2. * PI * (z - q) * 2.); - // c1(jx, jy, jz) = c1(jx+1, jy, jz); - } - } - } - } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - c1(jx, jy, jz) = - 1. + 0.15 * exp(-50. * pow(x - p, 2) * 2.) * sin(2. * PI * (z - q) * 2.); - // c1(jx, jy, jz) = c1(jx-1, jy, jz); - } - } + const Field3D b_1 = forward_laplace(f_1, a_1, c_1, d_1); + + int test_num = 0; + check_laplace(++test_num, "PETSc 2nd order", *invert, INVERT_AC_GRAD, INVERT_AC_GRAD, + a_1, c_1, d_1, b_1, f_1, mesh->ystart, dump); + + ///////////////////////////////////////////////// + // Test 2: Gaussian x-profiles, 4th order Krylov + + check_laplace(++test_num, "PETSc 4th order", *invert_4th, INVERT_AC_GRAD, + INVERT_AC_GRAD, a_1, c_1, d_1, b_1, f_1, mesh->ystart, dump); + + //////////////////////////////////////////////////////////////////////////////////////// + // Test 3+4: Gaussian x-profiles, z-independent coefficients and compare with SPT method + + const Field2D a_3 = DC(a_1); + const Field2D c_3 = DC(c_1); + const Field2D d_3 = DC(d_1); + const Field3D b_3 = forward_laplace(f_1, a_3, c_3, d_3); + + check_laplace(++test_num, "with coefficients constant in z, PETSc 2nd order", *invert, + INVERT_AC_GRAD, INVERT_AC_GRAD, a_3, c_3, d_3, b_3, f_1, mesh->ystart, + dump); + + Options* SPT_options = Options::getRoot()->getSection("SPT"); + auto invert_SPT = Laplacian::create(SPT_options); + + check_laplace(++test_num, "with coefficients constant in z, default solver", + *invert_SPT, INVERT_AC_GRAD, INVERT_AC_GRAD | INVERT_DC_GRAD, a_3, c_3, + d_3, b_3, f_1, mesh->ystart, dump); + + ////////////////////////////////////////////// + // Test 5: Cosine x-profiles, 2nd order Krylov + Field3D f_5 = generate_f5(*mesh); + Field3D a_5 = generate_a5(*mesh); + Field3D c_5 = generate_c5(*mesh); + Field3D d_5 = generate_d5(*mesh); + + mesh->communicate(f_5, a_5, c_5, d_5); + + const Field3D b_5 = forward_laplace(f_5, a_5, c_5, d_5); + + check_laplace(++test_num, "different profiles, PETSc 2nd order", *invert, + INVERT_AC_GRAD, INVERT_AC_GRAD, a_5, c_5, d_5, b_5, f_5, mesh->ystart, + dump); + + ////////////////////////////////////////////// + // Test 6: Cosine x-profiles, 4th order Krylov + + check_laplace(++test_num, "different profiles, PETSc 4th order", *invert_4th, + INVERT_AC_GRAD, INVERT_AC_GRAD, a_5, c_5, d_5, b_5, f_5, mesh->ystart, + dump); + + ////////////////////////////////////////////////////////////////////////////////////// + // Test 7+8: Cosine x-profiles, z-independent coefficients and compare with SPT method + + const Field2D a_7 = DC(a_5); + const Field2D c_7 = DC(c_5); + const Field2D d_7 = DC(d_5); + const Field3D b_7 = forward_laplace(f_5, a_7, c_7, d_7); + + check_laplace(++test_num, + "different profiles, with coefficients constant in z, PETSc 2nd order", + *invert, INVERT_AC_GRAD, INVERT_AC_GRAD, a_7, c_7, d_7, b_7, f_5, + mesh->ystart, dump); + + check_laplace(++test_num, + "different profiles, with coefficients constant in z, default solver", + *invert_SPT, INVERT_AC_GRAD, INVERT_AC_GRAD | INVERT_DC_GRAD, a_7, c_7, + d_7, b_7, f_5, mesh->ystart, dump); + + // Write and close the output file + bout::writeDefaultOutputFile(dump); + + MPI_Barrier(BoutComm::get()); // Wait for all processors to write data + } + + bout::checkForUnusedOptions(); + + BoutFinalise(); + return 0; +} + +BoutReal max_error_at_ystart(const Field3D& error) { + const auto* mesh = error.getMesh(); + BoutReal local_max_error = error(mesh->xstart, mesh->ystart, 0); + + for (int jx = mesh->xstart; jx <= mesh->xend; jx++) { + for (int jz = 0; jz < mesh->LocalNz; jz++) { + if (local_max_error < error(jx, mesh->ystart, jz)) { + local_max_error = error(jx, mesh->ystart, jz); } } + } - p = 0.612547; - q = 0.30908712; - a1.allocate(); - for (int jx = mesh->xstart; jx <= mesh->xend; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - a1(jx, jy, jz) = - -1. + 0.1 * exp(-50. * pow(x - p, 2) * 2.5) * sin(2. * PI * (z - q) * 7.); + BoutReal max_error = BoutNaN; + + MPI_Allreduce(&local_max_error, &max_error, 1, MPI_DOUBLE, MPI_MAX, BoutComm::get()); + + return max_error; +} + +void apply_flat_boundary(Field3D& bcoef) { + const Mesh& mesh = *bcoef.getMesh(); + if (mesh.firstX()) { + for (int jx = mesh.xstart - 1; jx >= 0; jx--) { + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + bcoef(jx, jy, jz) = bcoef(jx + 1, jy, jz); } } } - if (mesh->firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - a1(jx, jy, jz) = - -1. + 0.1 * exp(-50. * pow(x - p, 2) * 2.5) * sin(2. * PI * (z - q) * 7.); - // a1(jx, jy, jz) = a1(jx+1, jy, jz); - } + } + if (mesh.lastX()) { + for (int jx = mesh.xend + 1; jx < mesh.LocalNx; jx++) { + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + bcoef(jx, jy, jz) = bcoef(jx - 1, jy, jz); } } } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - a1(jx, jy, jz) = - -1. + 0.1 * exp(-50. * pow(x - p, 2) * 2.5) * sin(2. * PI * (z - q) * 7.); - // a1(jx, jy, jz) = a1(jx-1, jy, jz); - } - } + } +} + +Field3D generate_f1(const Mesh& mesh) { + const BoutReal nx = mesh.GlobalNx - 2 * mesh.xstart - 1; + const BoutReal nz = mesh.GlobalNz; + + constexpr BoutReal p = 0.39503274; // NOLINT + constexpr BoutReal q = 0.20974396; // NOLINT + + Field3D result; + result.allocate(); + for (int jx = mesh.xstart; jx <= mesh.xend; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + //make the gradients zero at both x-boundaries + result(jx, jy, jz) = 0. + + exp(-(100. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) + - 50. + * (2. * p * exp(-100. * pow(-p, 2)) * x + + (-p * exp(-100. * pow(-p, 2)) + - (1 - p) * exp(-100. * pow(1 - p, 2))) + * pow(x, 2)) + * exp(-(1. - cos(2. * PI * (z - q)))); } } + } + if (mesh.firstX()) { + for (int jx = mesh.xstart - 1; jx >= 0; jx--) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; - checkData(f1); - checkData(a1); - checkData(c1); - checkData(d1); - - mesh->communicate(f1, a1, c1, d1); - - b1 = d1 * Delp2(f1) + Grad_perp(c1) * Grad_perp(f1) / c1 + a1 * f1; - - if (mesh->firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - b1(jx, jy, jz) = b1(jx + 1, jy, jz); - } + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + //make the gradients zero at both x-boundaries + result(jx, jy, jz) = 0. + + exp(-(60. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) + - 50. + * (2. * p * exp(-60. * pow(-p, 2)) * x + + (-p * exp(-60. * pow(-p, 2)) + - (1 - p) * exp(-60. * pow(1 - p, 2))) + * pow(x, 2)) + * exp(-(1. - cos(2. * PI * (z - q)))); } } } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - b1(jx, jy, jz) = b1(jx - 1, jy, jz); - } + } + if (mesh.lastX()) { + for (int jx = mesh.xend + 1; jx < mesh.LocalNx; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + //make the gradients zero at both x-boundaries + result(jx, jy, jz) = 0. + + exp(-(60. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) + - 50. + * (2. * p * exp(-60. * pow(-p, 2)) * x + + (-p * exp(-60. * pow(-p, 2)) + - (1 - p) * exp(-60. * pow(1 - p, 2))) + * pow(x, 2)) + * exp(-(1. - cos(2. * PI * (z - q)))); } } } + } - invert->setInnerBoundaryFlags(INVERT_AC_GRAD); - invert->setOuterBoundaryFlags(INVERT_AC_GRAD); - invert->setCoefA(a1); - invert->setCoefC(c1); - invert->setCoefD(d1); - - checkData(b1); - - try { - sol1 = invert->solve(sliceXZ(b1, mesh->ystart)); - error1 = (f1 - sol1) / f1; - absolute_error1 = f1 - sol1; - // max_error1 = max_error_at_ystart(abs(error1)); - max_error1 = max_error_at_ystart(abs(absolute_error1)); - } catch (BoutException& err) { - output << "BoutException occured in invert->solve(b1): " << err.what() << endl; - max_error1 = -1; - } + checkData(result); + result.applyBoundary("neumann"); + return result; +} - output << endl << "Test 1: PETSc 2nd order" << endl; - // output<<"Time to set up is "<setInnerBoundaryFlags(INVERT_AC_GRAD); - invert_4th->setOuterBoundaryFlags(INVERT_AC_GRAD); - invert_4th->setGlobalFlags(INVERT_4TH_ORDER); - invert_4th->setCoefA(a1); - invert_4th->setCoefC(c1); - invert_4th->setCoefD(d1); - - try { - sol2 = invert_4th->solve(sliceXZ(b1, mesh->ystart)); - error2 = (f1 - sol2) / f1; - absolute_error2 = f1 - sol2; - // max_error2 = max_error_at_ystart(abs(error2)); - max_error2 = max_error_at_ystart(abs(absolute_error2)); - } catch (BoutException& err) { - output << "BoutException occured in invert->solve(b1): " << err.what() << endl; - max_error2 = -1; + constexpr BoutReal p = 0.512547; // NOLINT + constexpr BoutReal q = 0.30908712; // NOLINT + Field3D result; + result.allocate(); + for (int jx = mesh.xstart; jx <= mesh.xend; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + 1. + 0.2 * exp(-50. * pow(x - p, 2) / 4.) * sin(2. * PI * (z - q) * 3.); + } } - - output << endl << "Test 2: PETSc 4th order" << endl; - // output<<"Time to set up is "<firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - b3(jx, jy, jz) = b3(jx + 1, jy, jz); - } + } + if (mesh.firstX()) { + for (int jx = mesh.xstart - 1; jx >= 0; jx--) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + 1. + 0.2 * exp(-50. * pow(x - p, 2) / 4.) * sin(2. * PI * (z - q) * 3.); } } } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - b3(jx, jy, jz) = b3(jx - 1, jy, jz); - } + } + if (mesh.lastX()) { + for (int jx = mesh.xend + 1; jx < mesh.LocalNx; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + 1. + 0.2 * exp(-50. * pow(x - p, 2) / 4.) * sin(2. * PI * (z - q) * 3.); } } } + } + checkData(result); + return result; +} - invert->setInnerBoundaryFlags(INVERT_AC_GRAD); - invert->setOuterBoundaryFlags(INVERT_AC_GRAD); - invert->setCoefA(a3); - invert->setCoefC(c3); - invert->setCoefD(d3); - - try { - sol3 = invert->solve(sliceXZ(b3, mesh->ystart)); - error3 = (f1 - sol3) / f1; - absolute_error3 = f1 - sol3; - // max_error3 = max_error_at_ystart(abs(error3)); - max_error3 = max_error_at_ystart(abs(absolute_error3)); - } catch (BoutException& err) { - output << "BoutException occured in invert->solve(b3): " << err.what() << endl; - max_error3 = -1; - } +Field3D generate_c1(const Mesh& mesh) { + const BoutReal nx = mesh.GlobalNx - 2 * mesh.xstart - 1; + const BoutReal nz = mesh.GlobalNz; - output << endl << "Test 3: with coefficients constant in z, PETSc 2nd order" << endl; - // output<<"Time to set up is "<getSection("SPT"); - auto invert_SPT = Laplacian::create(SPT_options); - invert_SPT->setInnerBoundaryFlags(INVERT_AC_GRAD); - invert_SPT->setOuterBoundaryFlags(INVERT_AC_GRAD | INVERT_DC_GRAD); - invert_SPT->setCoefA(a3); - invert_SPT->setCoefC(c3); - invert_SPT->setCoefD(d3); - - sol4 = invert_SPT->solve(sliceXZ(b3, mesh->ystart)); - error4 = (f1 - sol4) / f1; - absolute_error4 = f1 - sol4; - // max_error4 = max_error_at_ystart(abs(error4)); - max_error4 = max_error_at_ystart(abs(absolute_error4)); - - output << endl << "Test 4: with coefficients constant in z, default solver" << endl; - // output<<"Time to set up is "<xstart; jx <= mesh->xend; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - f5(jx, jy, jz) = - 0. + exp(-(50. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) - - 50. - * (2. * p * exp(-50. * pow(-p, 2)) * x - + (-p * exp(-50. * pow(-p, 2)) - - (1 - p) * exp(-50. * pow(1 - p, 2))) - * pow(x, 2)) - * exp(-( - 1. - - cos(2. * PI - * (z - q)))) //make the gradients zero at both x-boundaries - ; - } + constexpr BoutReal p = 0.18439023; // NOLINT + constexpr BoutReal q = 0.401089473; // NOLINT + Field3D result; + result.allocate(); + for (int jx = mesh.xstart; jx <= mesh.xend; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + 1. + 0.15 * exp(-50. * pow(x - p, 2) * 2.) * sin(2. * PI * (z - q) * 2.); } } - if (mesh->firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - f5(jx, jy, jz) = - 0. + exp(-(50. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) - - 50. - * (2. * p * exp(-50. * pow(-p, 2)) * x - + (-p * exp(-50. * pow(-p, 2)) - - (1 - p) * exp(-50. * pow(1 - p, 2))) - * pow(x, 2)) - * exp(-( - 1. - - cos( - 2. * PI - * (z - q)))); //make the gradients zero at both x-boundaries - } + } + if (mesh.firstX()) { + for (int jx = mesh.xstart - 1; jx >= 0; jx--) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + 1. + 0.15 * exp(-50. * pow(x - p, 2) * 2.) * sin(2. * PI * (z - q) * 2.); } } } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - f5(jx, jy, jz) = - 0. + exp(-(50. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) - - 50. - * (2. * p * exp(-50. * pow(-p, 2)) * x - + (-p * exp(-50. * pow(-p, 2)) - - (1 - p) * exp(-50. * pow(1 - p, 2))) - * pow(x, 2)) - * exp(-( - 1. - - cos( - 2. * PI - * (z - q)))); //make the gradients zero at both x-boundaries - } + } + if (mesh.lastX()) { + for (int jx = mesh.xend + 1; jx < mesh.LocalNx; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + 1. + 0.15 * exp(-50. * pow(x - p, 2) * 2.) * sin(2. * PI * (z - q) * 2.); } } } + } - p = 0.63298589; - q = 0.889237890; - d5.allocate(); - for (int jx = mesh->xstart; jx <= mesh->xend; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - d5(jx, jy, jz) = 1. + p * cos(2. * PI * x) * sin(2. * PI * (z - q) * 3.); - } + checkData(result); + return result; +} + +Field3D generate_a1(const Mesh& mesh) { + const BoutReal nx = mesh.GlobalNx - 2 * mesh.xstart - 1; + const BoutReal nz = mesh.GlobalNz; + + constexpr BoutReal p = 0.612547; // NOLINT + constexpr BoutReal q = 0.30908712; // NOLINT + Field3D result; + result.allocate(); + for (int jx = mesh.xstart; jx <= mesh.xend; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + -1. + 0.1 * exp(-50. * pow(x - p, 2) * 2.5) * sin(2. * PI * (z - q) * 7.); } } - if (mesh->firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - d5(jx, jy, jz) = 1. + p * cos(2. * PI * x) * sin(2. * PI * (z - q) * 3.); - } + } + if (mesh.firstX()) { + for (int jx = mesh.xstart - 1; jx >= 0; jx--) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + -1. + 0.1 * exp(-50. * pow(x - p, 2) * 2.5) * sin(2. * PI * (z - q) * 7.); } } } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - d5(jx, jy, jz) = 1. + p * cos(2. * PI * x) * sin(2. * PI * (z - q) * 3.); - } + } + if (mesh.lastX()) { + for (int jx = mesh.xend + 1; jx < mesh.LocalNx; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + -1. + 0.1 * exp(-50. * pow(x - p, 2) * 2.5) * sin(2. * PI * (z - q) * 7.); } } } + } - p = 0.160983834; - q = 0.73050121087; - c5.allocate(); - for (int jx = mesh->xstart; jx <= mesh->xend; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - c5(jx, jy, jz) = 1. + p * cos(2. * PI * x * 5) * sin(2. * PI * (z - q) * 2.); - } + checkData(result); + return result; +} + +Field3D generate_f5(const Mesh& mesh) { + const BoutReal nx = mesh.GlobalNx - 2 * mesh.xstart - 1; + const BoutReal nz = mesh.GlobalNz; + constexpr BoutReal p = 0.623901; // NOLINT + constexpr BoutReal q = 0.01209489; // NOLINT + Field3D result; + result.allocate(); + for (int jx = mesh.xstart; jx <= mesh.xend; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + //make the gradients zero at both x-boundaries + result(jx, jy, jz) = + 0. + exp(-(50. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) + - 50. + * (2. * p * exp(-50. * pow(-p, 2)) * x + + (-p * exp(-50. * pow(-p, 2)) - (1 - p) * exp(-50. * pow(1 - p, 2))) + * pow(x, 2)) + * exp(-(1. - cos(2. * PI * (z - q)))); } } - if (mesh->firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - c5(jx, jy, jz) = 1. + p * cos(2. * PI * x * 5) * sin(2. * PI * (z - q) * 2.); - } + } + if (mesh.firstX()) { + for (int jx = mesh.xstart - 1; jx >= 0; jx--) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + //make the gradients zero at both x-boundaries + result(jx, jy, jz) = 0. + + exp(-(50. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) + - 50. + * (2. * p * exp(-50. * pow(-p, 2)) * x + + (-p * exp(-50. * pow(-p, 2)) + - (1 - p) * exp(-50. * pow(1 - p, 2))) + * pow(x, 2)) + * exp(-(1. - cos(2. * PI * (z - q)))); } } } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - c5(jx, jy, jz) = 1. + p * cos(2. * PI * x * 5) * sin(2. * PI * (z - q) * 2.); - } + } + if (mesh.lastX()) { + for (int jx = mesh.xend + 1; jx < mesh.LocalNx; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + //make the gradients zero at both x-boundaries + result(jx, jy, jz) = 0. + + exp(-(50. * pow(x - p, 2) + 1. - cos(2. * PI * (z - q)))) + - 50. + * (2. * p * exp(-50. * pow(-p, 2)) * x + + (-p * exp(-50. * pow(-p, 2)) + - (1 - p) * exp(-50. * pow(1 - p, 2))) + * pow(x, 2)) + * exp(-(1. - cos(2. * PI * (z - q)))); } } } + } + result.applyBoundary("neumann"); + checkData(result); + return result; +} - p = 0.5378950; - q = 0.2805870; - a5.allocate(); - for (int jx = mesh->xstart; jx <= mesh->xend; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - a5(jx, jy, jz) = -1. + p * cos(2. * PI * x * 2.) * sin(2. * PI * (z - q) * 7.); - } +Field3D generate_d5(const Mesh& mesh) { + const BoutReal nx = mesh.GlobalNx - 2 * mesh.xstart - 1; + const BoutReal nz = mesh.GlobalNz; + constexpr BoutReal p = 0.63298589; // NOLINT + constexpr BoutReal q = 0.889237890; // NOLINT + Field3D result; + result.allocate(); + for (int jx = mesh.xstart; jx <= mesh.xend; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = 1. + p * cos(2. * PI * x) * sin(2. * PI * (z - q) * 3.); } } - if (mesh->firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - a5(jx, jy, jz) = - -1. + p * cos(2. * PI * x * 2.) * sin(2. * PI * (z - q) * 7.); - } + } + if (mesh.firstX()) { + for (int jx = mesh.xstart - 1; jx >= 0; jx--) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = 1. + p * cos(2. * PI * x) * sin(2. * PI * (z - q) * 3.); } } } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - BoutReal x = BoutReal(mesh->getGlobalXIndex(jx) - mesh->xstart) / nx; - BoutReal z = BoutReal(jz) / nz; - a5(jx, jy, jz) = - -1. + p * cos(2. * PI * x * 2.) * sin(2. * PI * (z - q) * 7.); - } + } + if (mesh.lastX()) { + for (int jx = mesh.xend + 1; jx < mesh.LocalNx; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = 1. + p * cos(2. * PI * x) * sin(2. * PI * (z - q) * 3.); } } } + } + checkData(result); + return result; +} - f5.applyBoundary("neumann"); - mesh->communicate(f5, a5, c5, d5); +Field3D generate_c5(const Mesh& mesh) { + const BoutReal nx = mesh.GlobalNx - 2 * mesh.xstart - 1; + const BoutReal nz = mesh.GlobalNz; + constexpr BoutReal p = 0.160983834; // NOLINT + constexpr BoutReal q = 0.73050121087; // NOLINT - b5 = d5 * Delp2(f5) + Grad_perp(c5) * Grad_perp(f5) / c5 + a5 * f5; - if (mesh->firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - b5(jx, jy, jz) = b5(jx + 1, jy, jz); - } - } + Field3D result; + + result.allocate(); + for (int jx = mesh.xstart; jx <= mesh.xend; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = 1. + p * cos(2. * PI * x * 5) * sin(2. * PI * (z - q) * 2.); } } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - b5(jx, jy, jz) = b5(jx - 1, jy, jz); - } + } + if (mesh.firstX()) { + for (int jx = mesh.xstart - 1; jx >= 0; jx--) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + 1. + p * cos(2. * PI * x * 5) * sin(2. * PI * (z - q) * 2.); } } } - - invert->setInnerBoundaryFlags(INVERT_AC_GRAD); - invert->setOuterBoundaryFlags(INVERT_AC_GRAD); - invert->setCoefA(a5); - invert->setCoefC(c5); - invert->setCoefD(d5); - - try { - sol5 = invert->solve(sliceXZ(b5, mesh->ystart)); - error5 = (f5 - sol5) / f5; - absolute_error5 = f5 - sol5; - // max_error5 = max_error_at_ystart(abs(error5)); - max_error5 = max_error_at_ystart(abs(absolute_error5)); - } catch (BoutException& err) { - output << "BoutException occured in invert->solve(b5): " << err.what() << endl; - max_error5 = -1; - } - - output << endl << "Test 5: different profiles, PETSc 2nd order" << endl; - // output<<"Time to set up is "<setInnerBoundaryFlags(INVERT_AC_GRAD); - invert_4th->setOuterBoundaryFlags(INVERT_AC_GRAD); - invert_4th->setGlobalFlags(INVERT_4TH_ORDER); - invert_4th->setCoefA(a5); - invert_4th->setCoefC(c5); - invert_4th->setCoefD(d5); - - try { - sol6 = invert_4th->solve(sliceXZ(b5, mesh->ystart)); - error6 = (f5 - sol6) / f5; - absolute_error6 = f5 - sol6; - // max_error6 = max_error_at_ystart(abs(error6)); - max_error6 = max_error_at_ystart(abs(absolute_error6)); - } catch (BoutException& err) { - output - << "BoutException occured in invert->solve(b6): Laplacian inversion failed to " - "converge (probably)" - << endl; - max_error6 = -1; + } + if (mesh.lastX()) { + for (int jx = mesh.xend + 1; jx < mesh.LocalNx; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + 1. + p * cos(2. * PI * x * 5) * sin(2. * PI * (z - q) * 2.); + } + } } + } + checkData(result); + return result; +} - output << endl << "Test 6: different profiles, PETSc 4th order" << endl; - // output<<"Time to set up is "<firstX()) { - for (int jx = mesh->xstart - 1; jx >= 0; jx--) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - b7(jx, jy, jz) = b7(jx + 1, jy, jz); - } - } +Field3D generate_a5(const Mesh& mesh) { + const BoutReal nx = mesh.GlobalNx - 2 * mesh.xstart - 1; + const BoutReal nz = mesh.GlobalNz; + constexpr BoutReal p = 0.5378950; // NOLINT + constexpr BoutReal q = 0.2805870; // NOLINT + Field3D result; + result.allocate(); + for (int jx = mesh.xstart; jx <= mesh.xend; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + -1. + p * cos(2. * PI * x * 2.) * sin(2. * PI * (z - q) * 7.); } } - if (mesh->lastX()) { - for (int jx = mesh->xend + 1; jx < mesh->LocalNx; jx++) { - for (int jy = 0; jy < mesh->LocalNy; jy++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - b7(jx, jy, jz) = b7(jx - 1, jy, jz); - } + } + if (mesh.firstX()) { + for (int jx = mesh.xstart - 1; jx >= 0; jx--) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + -1. + p * cos(2. * PI * x * 2.) * sin(2. * PI * (z - q) * 7.); } } } - - invert->setInnerBoundaryFlags(INVERT_AC_GRAD); - invert->setOuterBoundaryFlags(INVERT_AC_GRAD); - invert->setCoefA(a7); - invert->setCoefC(c7); - invert->setCoefD(d7); - - try { - sol7 = invert->solve(sliceXZ(b7, mesh->ystart)); - error7 = (f5 - sol7) / f5; - absolute_error7 = f5 - sol7; - // max_error7 = max_error_at_ystart(abs(error7)); - max_error7 = max_error_at_ystart(abs(absolute_error7)); - } catch (BoutException& err) { - output << "BoutException occured in invert->solve(b7): " << err.what() << endl; - max_error7 = -1; - } - - output - << endl - << "Test 7: different profiles, with coefficients constant in z, PETSc 2nd order" - << endl; - // output<<"Time to set up is "<setInnerBoundaryFlags(INVERT_AC_GRAD); - invert_SPT->setOuterBoundaryFlags(INVERT_AC_GRAD | INVERT_DC_GRAD); - invert_SPT->setCoefA(a7); - invert_SPT->setCoefC(c7); - invert_SPT->setCoefD(d7); - - sol8 = invert_SPT->solve(sliceXZ(b7, mesh->ystart)); - error8 = (f5 - sol8) / f5; - absolute_error8 = f5 - sol8; - // max_error8 = max_error_at_ystart(abs(error8)); - max_error8 = max_error_at_ystart(abs(absolute_error8)); - - output - << endl - << "Test 8: different profiles, with coefficients constant in z, default solver" - << endl; - // output<<"Time to set up is "<xstart, mesh->ystart, 0); - - for (int jx = mesh->xstart; jx <= mesh->xend; jx++) { - for (int jz = 0; jz < mesh->LocalNz; jz++) { - if (local_max_error < error(jx, mesh->ystart, jz)) { - local_max_error = error(jx, mesh->ystart, jz); + if (mesh.lastX()) { + for (int jx = mesh.xend + 1; jx < mesh.LocalNx; jx++) { + const BoutReal x = BoutReal(mesh.getGlobalXIndex(jx) - mesh.xstart) / nx; + for (int jy = 0; jy < mesh.LocalNy; jy++) { + for (int jz = 0; jz < mesh.LocalNz; jz++) { + const BoutReal z = BoutReal(jz) / nz; + result(jx, jy, jz) = + -1. + p * cos(2. * PI * x * 2.) * sin(2. * PI * (z - q) * 7.); + } } } } - - BoutReal max_error; - - MPI_Allreduce(&local_max_error, &max_error, 1, MPI_DOUBLE, MPI_MAX, BoutComm::get()); - - return max_error; + checkData(result); + return result; } diff --git a/tests/integrated/test-solver/test_solver.cxx b/tests/integrated/test-solver/test_solver.cxx index ee64c6097f..2e4345c8cc 100644 --- a/tests/integrated/test-solver/test_solver.cxx +++ b/tests/integrated/test-solver/test_solver.cxx @@ -146,8 +146,6 @@ int main(int argc, char** argv) { } } - BoutFinalise(false); - if (!errors.empty()) { output_test << "\n => Some failed tests\n\n"; for (auto& error : errors) { diff --git a/tests/integrated/test-squash/runtest b/tests/integrated/test-squash/runtest index 692d561c59..c79cba0faf 100755 --- a/tests/integrated/test-squash/runtest +++ b/tests/integrated/test-squash/runtest @@ -15,7 +15,7 @@ import os.path # cores: 4 IGNORED_VARS_PATTERN = re.compile( - "(wtime|ncalls|arkode|cvode|run_id|run_restart_from|M.?SUB|N.?PE|iteration|wall_time|has_legacy_netcdf|hist_hi).*" + "(wtime|ncalls|arkode|cvode|run_id|run_restart_from|M.?SUB|N.?PE|iteration|wall_time|has_legacy_netcdf|hist_hi|openmp_threads).*" ) diff --git a/tests/integrated/test-twistshift-staggered/test-twistshift.cxx b/tests/integrated/test-twistshift-staggered/test-twistshift.cxx index 87b9e0a094..33b45b662d 100644 --- a/tests/integrated/test-twistshift-staggered/test-twistshift.cxx +++ b/tests/integrated/test-twistshift-staggered/test-twistshift.cxx @@ -4,11 +4,11 @@ int main(int argc, char** argv) { BoutInitialise(argc, argv); - Field3D test = FieldFactory::get()->create3D("test", nullptr, nullptr, CELL_YLOW); + using bout::globals::mesh; - Field3D test_aligned = toFieldAligned(test); + Field3D test = FieldFactory::get()->create3D("test", nullptr, mesh, CELL_YLOW); - using bout::globals::mesh; + Field3D test_aligned = toFieldAligned(test); // zero guard cells to check that communication is doing something for (int x = 0; x < mesh->LocalNx; x++) { @@ -25,12 +25,12 @@ int main(int argc, char** argv) { mesh->communicate(test_aligned); Options::root()["check"] = - FieldFactory::get()->create3D("check", nullptr, nullptr, CELL_YLOW); + FieldFactory::get()->create3D("check", nullptr, mesh, CELL_YLOW); Options::root()["test"] = test; Options::root()["test_aligned"] = test_aligned; - bout::writeDefaultOutputFile(); + bout::writeDefaultOutputFile(Options::root()); BoutFinalise(); } diff --git a/tests/integrated/test-twistshift/test-twistshift.cxx b/tests/integrated/test-twistshift/test-twistshift.cxx index ccde8b82b6..2c0fc79563 100644 --- a/tests/integrated/test-twistshift/test-twistshift.cxx +++ b/tests/integrated/test-twistshift/test-twistshift.cxx @@ -28,7 +28,7 @@ int main(int argc, char** argv) { Options::root()["test"] = test; Options::root()["test_aligned"] = test_aligned; - bout::writeDefaultOutputFile(); + bout::writeDefaultOutputFile(Options::root()); BoutFinalise(); } diff --git a/tests/integrated/test-yupdown-weights/test_yupdown_weights.cxx b/tests/integrated/test-yupdown-weights/test_yupdown_weights.cxx index 22d1fb9e07..e8a2982bfd 100644 --- a/tests/integrated/test-yupdown-weights/test_yupdown_weights.cxx +++ b/tests/integrated/test-yupdown-weights/test_yupdown_weights.cxx @@ -70,7 +70,7 @@ int main(int argc, char** argv) { Options::root()["ddy"] = ddy; Options::root()["ddy2"] = ddy2; - bout::writeDefaultOutputFile(); + bout::writeDefaultOutputFile(Options::root()); BoutFinalise(); diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index c0fd4a1e1f..c4ffa4fa75 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -19,6 +19,9 @@ if(NOT TARGET gtest) message(FATAL_ERROR "googletest not found! Have you disabled the git submodules (GIT_SUBMODULE)?") endif() +# Some unit tests require GMOCK, so make sure we build it +set(BUILD_GMOCK ON) + mark_as_advanced( BUILD_GMOCK BUILD_GTEST BUILD_SHARED_LIBS gmock_build_tests gtest_build_samples gtest_build_tests diff --git a/tests/unit/fake_parallel_mesh.hxx b/tests/unit/fake_parallel_mesh.hxx index c648bbab9c..805dcb2a0a 100644 --- a/tests/unit/fake_parallel_mesh.hxx +++ b/tests/unit/fake_parallel_mesh.hxx @@ -8,6 +8,8 @@ #include #include "../../src/mesh/impls/bout/boutmesh.hxx" +#include "bout/boundary_op.hxx" +#include "bout/boundary_region.hxx" #include "bout/boutcomm.hxx" #include "bout/coordinates.hxx" #include "bout/field2d.hxx" diff --git a/tests/unit/field/test_field.cxx b/tests/unit/field/test_field.cxx index b237ee3006..f458ffd6bc 100644 --- a/tests/unit/field/test_field.cxx +++ b/tests/unit/field/test_field.cxx @@ -33,6 +33,7 @@ class FieldSubClass : public Field { : Field(localmesh, location_in, directions_in) {} bool is3D() const override { return false; } + int size() const override { return 42; } }; } // namespace diff --git a/tests/unit/field/test_field_factory.cxx b/tests/unit/field/test_field_factory.cxx index c0d17915a4..ca51b845b3 100644 --- a/tests/unit/field/test_field_factory.cxx +++ b/tests/unit/field/test_field_factory.cxx @@ -37,32 +37,15 @@ class FieldFactoryCreationTest : public FakeMeshFixture { FieldFactory factory; - // We can't just decide which FieldFactory::create?D function to - // call with - // - // if (bout::utils::is_Field3D::value) { - // return factory.create3D(...); - // } else { - // return factory.create2D(...); - // } - // - // as this is *runtime* so the compiler still needs to evaluate both - // branches -- until C++17 when we can use `if constexpr ...` - template - T createDispatch(std::true_type, Args&&... args) { - return factory.create3D(std::forward(args)...); - } - - template - T createDispatch(std::false_type, Args&&... args) { - return factory.create2D(std::forward(args)...); - } - // Generic way of calling either FieldFactory::create2D or // FieldFactory::create3D template T create(Args&&... args) { - return createDispatch(bout::utils::is_Field3D{}, std::forward(args)...); + if constexpr (bout::utils::is_Field3D_v) { + return factory.create3D(std::forward(args)...); + } else { + return factory.create2D(std::forward(args)...); + } } }; @@ -227,7 +210,7 @@ TYPED_TEST(FieldFactoryCreationTest, CreateZStaggered) { auto expected = makeField( [](typename TypeParam::ind_type& index) -> BoutReal { auto offset = BoutReal{0.0}; - if (bout::utils::is_Field3D::value) { + if constexpr (bout::utils::is_Field3D_v) { offset = 0.5; } diff --git a/tests/unit/field/test_fieldgroup.cxx b/tests/unit/field/test_fieldgroup.cxx index bfb001fd2f..0374dfb894 100644 --- a/tests/unit/field/test_fieldgroup.cxx +++ b/tests/unit/field/test_fieldgroup.cxx @@ -283,9 +283,9 @@ TEST(FieldGroupTest, ConstIterator) { } TEST(FieldGroupTest, NotConstructableFromInt) { - EXPECT_FALSE((std::is_constructible::value)); + EXPECT_FALSE((std::is_constructible_v)); } TEST(FieldGroupTest, NotConstructableFromBoutReal) { - EXPECT_FALSE((std::is_constructible::value)); + EXPECT_FALSE((std::is_constructible_v)); } diff --git a/tests/unit/field/test_vector2d.cxx b/tests/unit/field/test_vector2d.cxx index 263c8d6d11..838876c02b 100644 --- a/tests/unit/field/test_vector2d.cxx +++ b/tests/unit/field/test_vector2d.cxx @@ -85,10 +85,6 @@ class Vector2DTest : public ::testing::Test { Mesh* mesh_staggered = nullptr; }; -constexpr int Vector2DTest::nx; -constexpr int Vector2DTest::ny; -constexpr int Vector2DTest::nz; - TEST_F(Vector2DTest, ApplyBoundaryString) { Vector2D v; v = 0.0; diff --git a/tests/unit/include/bout/test_generic_factory.cxx b/tests/unit/include/bout/test_generic_factory.cxx index 9368356151..f8a1e20bfa 100644 --- a/tests/unit/include/bout/test_generic_factory.cxx +++ b/tests/unit/include/bout/test_generic_factory.cxx @@ -37,10 +37,6 @@ class BaseFactory : public Factory { static constexpr auto option_name = "type"; static constexpr auto default_type = "base"; }; -constexpr decltype(BaseFactory::type_name) BaseFactory::type_name; -constexpr decltype(BaseFactory::section_name) BaseFactory::section_name; -constexpr decltype(BaseFactory::option_name) BaseFactory::option_name; -constexpr decltype(BaseFactory::default_type) BaseFactory::default_type; BaseFactory::RegisterInFactory registerme("base"); BaseFactory::RegisterInFactory registerme1("derived1"); @@ -76,11 +72,6 @@ class ComplicatedFactory static constexpr auto default_type = "basecomplicated"; }; -constexpr decltype(ComplicatedFactory::type_name) ComplicatedFactory::type_name; -constexpr decltype(ComplicatedFactory::section_name) ComplicatedFactory::section_name; -constexpr decltype(ComplicatedFactory::option_name) ComplicatedFactory::option_name; -constexpr decltype(ComplicatedFactory::default_type) ComplicatedFactory::default_type; - namespace { ComplicatedFactory::RegisterInFactory registerme3("basecomplicated"); ComplicatedFactory::RegisterInFactory diff --git a/tests/unit/include/bout/test_hypre_interface.cxx b/tests/unit/include/bout/test_hypre_interface.cxx index b7a7c2c50c..e2eefab9a8 100644 --- a/tests/unit/include/bout/test_hypre_interface.cxx +++ b/tests/unit/include/bout/test_hypre_interface.cxx @@ -185,7 +185,7 @@ class HypreMatrixTest : public FakeMeshFixture { indexA = ind_type((1 + field.getNy()) * field.getNz() + 1, field.getNy(), field.getNz()); - if (std::is_same::value) { + if constexpr (std::is_same_v) { indexB = indexA.zp(); iWD0 = indexB.zm(); @@ -309,7 +309,7 @@ TYPED_TEST(HypreMatrixTest, SetElements) { auto j_index = static_cast(this->indexer->getGlobal(j)); HYPRE_Int ncolumns{1}; HYPRE_Complex value; - BOUT_OMP(critical) + BOUT_OMP_SAFE(critical) { HYPRE_IJMatrixGetValues(raw_matrix, 1, &ncolumns, &i_index, &j_index, &value); } if (i == j) { EXPECT_EQ(static_cast(value), @@ -389,7 +389,7 @@ TYPED_TEST(HypreMatrixTest, YUp) { HypreMatrix matrix(this->indexer); - if (std::is_same::value) { + if constexpr (std::is_same_v) { EXPECT_THROW(matrix.yup(), BoutException); return; } @@ -398,7 +398,7 @@ TYPED_TEST(HypreMatrixTest, YUp) { MockTransform* transform = this->pt; const BoutReal value = 42.0; - if (std::is_same::value) { + if constexpr (std::is_same_v) { expected(this->indexA, this->indexB) = value; } else { EXPECT_CALL(*transform, getWeightsForYUpApproximation( @@ -422,7 +422,7 @@ TYPED_TEST(HypreMatrixTest, YDown) { HypreMatrix matrix(this->indexer); - if (std::is_same::value) { + if constexpr (std::is_same_v) { EXPECT_THROW(matrix.yup(), BoutException); return; } @@ -431,7 +431,7 @@ TYPED_TEST(HypreMatrixTest, YDown) { MockTransform* transform = this->pt; const BoutReal value = 42.0; - if (std::is_same::value) { + if constexpr (std::is_same_v) { expected(this->indexB, this->indexA) = value; } else { EXPECT_CALL(*transform, getWeightsForYDownApproximation( diff --git a/tests/unit/include/bout/test_petsc_indexer.cxx b/tests/unit/include/bout/test_petsc_indexer.cxx index 40c29ddfbd..3c20de9989 100644 --- a/tests/unit/include/bout/test_petsc_indexer.cxx +++ b/tests/unit/include/bout/test_petsc_indexer.cxx @@ -39,11 +39,10 @@ class IndexerTest : public FakeMeshFixture { globalStarIndexer(bout::globals::mesh, starStencil(bout::globals::mesh)), globalDefaultIndexer(bout::globals::mesh), guardx(bout::globals::mesh->getNXPE()), - guardy(std::is_same::value ? 0 : bout::globals::mesh->getNYPE()), + guardy(std::is_same_v ? 0 : bout::globals::mesh->getNYPE()), nx(bout::globals::mesh->LocalNx - 2 * guardx), - ny(std::is_same::value ? 1 - : bout::globals::mesh->LocalNy - 2 * guardy), - nz(std::is_same::value ? 1 : bout::globals::mesh->LocalNz), + ny(std::is_same_v ? 1 : bout::globals::mesh->LocalNy - 2 * guardy), + nz(std::is_same_v ? 1 : bout::globals::mesh->LocalNz), mesh2(2, 2, 2) { mesh2.createDefaultRegions(); mesh2.setCoordinates(nullptr); @@ -82,15 +81,15 @@ TYPED_TEST(IndexerTest, TestConvertIndex) { BOUT_FOR(i, f.getRegion("RGN_NOBNDRY")) { int global = this->globalSquareIndexer.getGlobal(i); EXPECT_GE(global, 0); - BOUT_OMP(critical) + BOUT_OMP_SAFE(critical) EXPECT_TRUE(indicesGlobalSquare.insert(global).second); global = this->globalStarIndexer.getGlobal(i); EXPECT_GE(global, 0); - BOUT_OMP(critical) + BOUT_OMP_SAFE(critical) EXPECT_TRUE(indicesGlobalStar.insert(global).second); global = this->globalDefaultIndexer.getGlobal(i); EXPECT_GE(global, 0); - BOUT_OMP(critical) + BOUT_OMP_SAFE(critical) EXPECT_TRUE(indicesGlobalDefault.insert(global).second); } @@ -98,25 +97,25 @@ TYPED_TEST(IndexerTest, TestConvertIndex) { BOUT_FOR(i, f.getRegion("RGN_XGUARDS")) { int global = this->globalSquareIndexer.getGlobal(i); EXPECT_GE(global, 0); - BOUT_OMP(critical) + BOUT_OMP_SAFE(critical) EXPECT_TRUE(indicesGlobalSquare.insert(global).second); global = this->globalStarIndexer.getGlobal(i); EXPECT_GE(global, 0); - BOUT_OMP(critical) + BOUT_OMP_SAFE(critical) EXPECT_TRUE(indicesGlobalStar.insert(global).second); EXPECT_LT(this->globalDefaultIndexer.getGlobal(i), 0); } // Check indices of Y guard cells are unique - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { BOUT_FOR(i, f.getRegion("RGN_YGUARDS")) { int global = this->globalSquareIndexer.getGlobal(i); EXPECT_GE(global, 0); - BOUT_OMP(critical) + BOUT_OMP_SAFE(critical) EXPECT_TRUE(indicesGlobalSquare.insert(global).second); global = this->globalStarIndexer.getGlobal(i); EXPECT_GE(global, 0); - BOUT_OMP(critical) + BOUT_OMP_SAFE(critical) EXPECT_TRUE(indicesGlobalStar.insert(global).second); EXPECT_LT(this->globalDefaultIndexer.getGlobal(i), 0); } @@ -178,7 +177,7 @@ TYPED_TEST(IndexerTest, TestGetRegionNobndry) { BOUT_FOR(i, rgn) { EXPECT_GE(i.x(), this->globalSquareIndexer.getMesh()->xstart); EXPECT_LE(i.x(), this->globalSquareIndexer.getMesh()->xend); - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { EXPECT_GE(i.y(), this->globalSquareIndexer.getMesh()->ystart); EXPECT_LE(i.y(), this->globalSquareIndexer.getMesh()->yend); } @@ -188,7 +187,7 @@ TYPED_TEST(IndexerTest, TestGetRegionNobndry) { BOUT_FOR(i, rgn) { EXPECT_GE(i.x(), this->globalStarIndexer.getMesh()->xstart); EXPECT_LE(i.x(), this->globalStarIndexer.getMesh()->xend); - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { EXPECT_GE(i.y(), this->globalStarIndexer.getMesh()->ystart); EXPECT_LE(i.y(), this->globalStarIndexer.getMesh()->yend); } @@ -198,7 +197,7 @@ TYPED_TEST(IndexerTest, TestGetRegionNobndry) { BOUT_FOR(i, rgn) { EXPECT_GE(i.x(), this->globalDefaultIndexer.getMesh()->xstart); EXPECT_LE(i.x(), this->globalDefaultIndexer.getMesh()->xend); - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { EXPECT_GE(i.y(), this->globalDefaultIndexer.getMesh()->ystart); EXPECT_LE(i.y(), this->globalDefaultIndexer.getMesh()->yend); } @@ -208,7 +207,7 @@ TYPED_TEST(IndexerTest, TestGetRegionNobndry) { BOUT_FOR(i, rgn) { EXPECT_GE(i.x(), this->localIndexer.getMesh()->xstart); EXPECT_LE(i.x(), this->localIndexer.getMesh()->xend); - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { EXPECT_GE(i.y(), this->localIndexer.getMesh()->ystart); EXPECT_LE(i.y(), this->localIndexer.getMesh()->yend); } @@ -230,7 +229,7 @@ TYPED_TEST(IndexerTest, TestGetRegionBndry) { TYPED_TEST(IndexerTest, TestGetRegionLowerY) { Region rgn; - if (std::is_same::value) { + if constexpr (std::is_same_v) { rgn = this->globalSquareIndexer.getRegionLowerY(); EXPECT_EQ(rgn.asUnique().size(), 0); rgn = this->globalStarIndexer.getRegionLowerY(); @@ -251,7 +250,7 @@ TYPED_TEST(IndexerTest, TestGetRegionLowerY) { TYPED_TEST(IndexerTest, TestGetRegionUpperY) { Region rgn; - if (std::is_same::value) { + if constexpr (std::is_same_v) { rgn = this->globalSquareIndexer.getRegionUpperY(); EXPECT_EQ(rgn.asUnique().size(), 0); rgn = this->globalStarIndexer.getRegionUpperY(); @@ -306,8 +305,8 @@ TYPED_TEST(IndexerTest, TestSparsityPatternAvailable) { } TYPED_TEST(IndexerTest, TestGetNumDiagonal) { - const int squareStencilInteriorSize = std::is_same::value ? 19 : 9, - starStencilInteriorSize = std::is_same::value ? 7 : 5, + const int squareStencilInteriorSize = std::is_same_v ? 19 : 9, + starStencilInteriorSize = std::is_same_v ? 7 : 5, boundsSize = 1; int numBoundaryCells = 0; for (int i : this->globalSquareIndexer.getNumDiagonal()) { diff --git a/tests/unit/include/bout/test_petsc_matrix.cxx b/tests/unit/include/bout/test_petsc_matrix.cxx index d55f384b9c..9ba2475096 100644 --- a/tests/unit/include/bout/test_petsc_matrix.cxx +++ b/tests/unit/include/bout/test_petsc_matrix.cxx @@ -31,6 +31,8 @@ using ::testing::Return; class MockTransform : public ParallelTransformIdentity { public: MockTransform(Mesh& mesh_in) : ParallelTransformIdentity(mesh_in){}; + MOCK_METHOD(std::vector, getWeightsForYApproximation, + (int i, int j, int k, int y_offset), (override)); MOCK_METHOD(std::vector, getWeightsForYUpApproximation, (int i, int j, int k), (override)); MOCK_METHOD(std::vector, getWeightsForYDownApproximation, @@ -55,7 +57,7 @@ class PetscMatrixTest : public FakeMeshFixture { stencil(squareStencil(bout::globals::mesh)), indexer(std::make_shared>(bout::globals::mesh, stencil)) { indexA = ind_type(field.getNy() * field.getNz() + 1, field.getNy(), field.getNz()); - if (std::is_same::value) { + if constexpr (std::is_same_v) { indexB = indexA.zp(); } else { indexB = indexA.yp(); @@ -63,7 +65,7 @@ class PetscMatrixTest : public FakeMeshFixture { iWU0 = indexB.xm(); iWU1 = indexB; iWU2 = indexB.xp(); - if (std::is_same::value) { + if constexpr (std::is_same_v) { iWD0 = indexB.zm(); iWD1 = indexB; iWD2 = indexB.zp(); @@ -175,7 +177,7 @@ TYPED_TEST(PetscMatrixTest, TestGetElements) { int i_ind = this->indexer->getGlobal(i); int j_ind = this->indexer->getGlobal(j); PetscScalar matContents; - BOUT_OMP(critical) + BOUT_OMP_SAFE(critical) MatGetValues(*rawmat, 1, &i_ind, 1, &j_ind, &matContents); if (i == j) { EXPECT_EQ(matContents, static_cast(i.ind)); @@ -263,25 +265,28 @@ TYPED_TEST(PetscMatrixTest, TestDestroy) { // Test getting yup TYPED_TEST(PetscMatrixTest, TestYUp) { - PetscMatrix matrix(this->indexer, false), expected(this->indexer, false); + PetscMatrix matrix(this->indexer, false); + PetscMatrix expected(this->indexer, false); MockTransform* transform = this->pt; SCOPED_TRACE("YUp"); - if (std::is_same::value) { + if constexpr (std::is_same_v) { EXPECT_THROW(matrix.yup(), BoutException); } else { - BoutReal val = 3.141592; - if (std::is_same::value) { + const BoutReal val = 3.141592; + if constexpr (std::is_same_v) { expected(this->indexA, this->indexB) = val; - } else if (std::is_same::value) { - EXPECT_CALL(*transform, getWeightsForYUpApproximation( - this->indexB.x(), this->indexA.y(), this->indexB.z())) + } else if constexpr (std::is_same_v) { + EXPECT_CALL(*transform, + getWeightsForYApproximation(this->indexB.x(), this->indexA.y(), + this->indexB.z(), 1)) .WillOnce(Return(this->yUpWeights)); expected(this->indexA, this->iWU0) = this->yUpWeights[0].weight * val; expected(this->indexA, this->iWU1) = this->yUpWeights[1].weight * val; expected(this->indexA, this->iWU2) = this->yUpWeights[2].weight * val; } matrix.yup()(this->indexA, this->indexB) = val; - Mat *rawmat = matrix.get(), *rawexp = expected.get(); + Mat* rawmat = matrix.get(); + Mat* rawexp = expected.get(); MatAssemblyBegin(*rawmat, MAT_FINAL_ASSEMBLY); MatAssemblyEnd(*rawmat, MAT_FINAL_ASSEMBLY); MatAssemblyBegin(*rawexp, MAT_FINAL_ASSEMBLY); @@ -292,25 +297,28 @@ TYPED_TEST(PetscMatrixTest, TestYUp) { // Test getting ydown TYPED_TEST(PetscMatrixTest, TestYDown) { - PetscMatrix matrix(this->indexer, false), expected(this->indexer, false); - BoutReal val = 3.141592; + PetscMatrix matrix(this->indexer, false); + PetscMatrix expected(this->indexer, false); + const BoutReal val = 3.141592; MockTransform* transform = this->pt; SCOPED_TRACE("YDown"); - if (std::is_same::value) { + if constexpr (std::is_same_v) { EXPECT_THROW(matrix.ydown(), BoutException); } else { - if (std::is_same::value) { + if constexpr (std::is_same_v) { expected(this->indexB, this->indexA) = val; - } else if (std::is_same::value) { - EXPECT_CALL(*transform, getWeightsForYDownApproximation( - this->indexA.x(), this->indexB.y(), this->indexA.z())) + } else if constexpr (std::is_same_v) { + EXPECT_CALL(*transform, + getWeightsForYApproximation(this->indexA.x(), this->indexB.y(), + this->indexA.z(), -1)) .WillOnce(Return(this->yDownWeights)); expected(this->indexB, this->iWD0) = this->yDownWeights[0].weight * val; expected(this->indexB, this->iWD1) = this->yDownWeights[1].weight * val; expected(this->indexB, this->iWD2) = this->yDownWeights[2].weight * val; } matrix.ydown()(this->indexB, this->indexA) = val; - Mat *rawmat = matrix.get(), *rawexp = expected.get(); + Mat* rawmat = matrix.get(); + Mat* rawexp = expected.get(); MatAssemblyBegin(*rawmat, MAT_FINAL_ASSEMBLY); MatAssemblyEnd(*rawmat, MAT_FINAL_ASSEMBLY); MatAssemblyBegin(*rawexp, MAT_FINAL_ASSEMBLY); @@ -321,12 +329,14 @@ TYPED_TEST(PetscMatrixTest, TestYDown) { // Test getting ynext(0) TYPED_TEST(PetscMatrixTest, TestYNext0) { - PetscMatrix matrix(this->indexer), expected(this->indexer); - BoutReal val = 3.141592; + PetscMatrix matrix(this->indexer); + PetscMatrix expected(this->indexer); + const BoutReal val = 3.141592; SCOPED_TRACE("YNext0"); matrix.ynext(0)(this->indexA, this->indexB) = val; expected(this->indexA, this->indexB) = val; - Mat rawmat = *matrix.get(), rawexp = *expected.get(); + Mat rawmat = *matrix.get(); + Mat rawexp = *expected.get(); MatAssemblyBegin(rawmat, MAT_FINAL_ASSEMBLY); MatAssemblyEnd(rawmat, MAT_FINAL_ASSEMBLY); MatAssemblyBegin(rawexp, MAT_FINAL_ASSEMBLY); @@ -336,22 +346,25 @@ TYPED_TEST(PetscMatrixTest, TestYNext0) { // Test getting ynext(1) TYPED_TEST(PetscMatrixTest, TestYNextPos) { - PetscMatrix matrix(this->indexer, false), expected(this->indexer, false); - BoutReal val = 3.141592; + PetscMatrix matrix(this->indexer, false); + PetscMatrix expected(this->indexer, false); + const BoutReal val = 3.141592; MockTransform* transform = this->pt; SCOPED_TRACE("YNextPos"); - if (std::is_same::value) { + if constexpr (std::is_same_v) { EXPECT_THROW(matrix.ynext(1), BoutException); } else { - if (std::is_same::value) { - EXPECT_CALL(*transform, getWeightsForYUpApproximation( - this->indexB.x(), this->indexA.y(), this->indexB.z())) + if constexpr (std::is_same_v) { + EXPECT_CALL(*transform, + getWeightsForYApproximation(this->indexB.x(), this->indexA.y(), + this->indexB.z(), 1)) .Times(2) .WillRepeatedly(Return(this->yDownWeights)); } matrix.ynext(1)(this->indexA, this->indexB) = val; expected.yup()(this->indexA, this->indexB) = val; - Mat *rawmat = matrix.get(), *rawexp = expected.get(); + Mat* rawmat = matrix.get(); + Mat* rawexp = expected.get(); MatAssemblyBegin(*rawmat, MAT_FINAL_ASSEMBLY); MatAssemblyEnd(*rawmat, MAT_FINAL_ASSEMBLY); MatAssemblyBegin(*rawexp, MAT_FINAL_ASSEMBLY); @@ -362,22 +375,25 @@ TYPED_TEST(PetscMatrixTest, TestYNextPos) { // Test getting ynext(-1) TYPED_TEST(PetscMatrixTest, TestYNextNeg) { - PetscMatrix matrix(this->indexer, false), expected(this->indexer, false); - BoutReal val = 3.141592; + PetscMatrix matrix(this->indexer, false); + PetscMatrix expected(this->indexer, false); + const BoutReal val = 3.141592; MockTransform* transform = this->pt; SCOPED_TRACE("YNextNeg"); - if (std::is_same::value) { + if constexpr (std::is_same_v) { EXPECT_THROW(matrix.ynext(-1), BoutException); } else { - if (std::is_same::value) { - EXPECT_CALL(*transform, getWeightsForYDownApproximation( - this->indexA.x(), this->indexB.y(), this->indexA.z())) + if constexpr (std::is_same_v) { + EXPECT_CALL(*transform, + getWeightsForYApproximation(this->indexA.x(), this->indexB.y(), + this->indexA.z(), -1)) .Times(2) .WillRepeatedly(Return(this->yDownWeights)); } matrix.ynext(-1)(this->indexB, this->indexA) = val; expected.ydown()(this->indexB, this->indexA) = val; - Mat *rawmat = matrix.get(), *rawexp = expected.get(); + Mat* rawmat = matrix.get(); + Mat* rawexp = expected.get(); MatAssemblyBegin(*rawmat, MAT_FINAL_ASSEMBLY); MatAssemblyEnd(*rawmat, MAT_FINAL_ASSEMBLY); MatAssemblyBegin(*rawexp, MAT_FINAL_ASSEMBLY); @@ -388,12 +404,15 @@ TYPED_TEST(PetscMatrixTest, TestYNextNeg) { // Test swap TYPED_TEST(PetscMatrixTest, TestSwap) { - PetscMatrix lhs(this->indexer), rhs(this->indexer); - Mat l0 = *lhs.get(), r0 = *rhs.get(); + PetscMatrix lhs(this->indexer); + PetscMatrix rhs(this->indexer); + Mat l0 = *lhs.get(); + Mat r0 = *rhs.get(); EXPECT_NE(l0, nullptr); EXPECT_NE(r0, nullptr); swap(lhs, rhs); - Mat l1 = *lhs.get(), r1 = *rhs.get(); + Mat l1 = *lhs.get(); + Mat r1 = *rhs.get(); EXPECT_NE(l0, l1); EXPECT_NE(r0, r1); EXPECT_EQ(l0, r1); diff --git a/tests/unit/include/bout/test_petsc_setters.cxx b/tests/unit/include/bout/test_petsc_setters.cxx index 3a916f59e0..d3d95280c0 100644 --- a/tests/unit/include/bout/test_petsc_setters.cxx +++ b/tests/unit/include/bout/test_petsc_setters.cxx @@ -10,89 +10,6 @@ #if BOUT_HAS_PETSC -///////////////// Test PetscVector::Element ///////////////// - -class PetscVectorElementTest : public ::testing::Test { -public: - WithQuietOutput all{output}; - Vec v; - PetscInt n = 10; - PetscScalar defaultVal = 1.; - PetscLib lib; - - PetscVectorElementTest() { - VecCreateMPI(MPI_COMM_WORLD, n, PETSC_DETERMINE, &v); - VecSet(v, defaultVal); - VecAssemblyBegin(v); - VecAssemblyEnd(v); - } - - virtual ~PetscVectorElementTest() { VecDestroy(&v); } -}; - -TEST_F(PetscVectorElementTest, AssignInsert) { - PetscVector::Element v1(&v, 1), v2(&v, 2), v3(&v, 3), v3b(&v, 3), v9(&v, 9); - v1 = 1.5; - v2 = 2.5; - v3 = 3.5; - v3b = 4.0; // Should overwrite previous call - v9 = 9.5; - VecAssemblyBegin(v); - VecAssemblyEnd(v); - PetscScalar* vecContents; - VecGetArray(v, &vecContents); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[0]); - EXPECT_DOUBLE_EQ(1.5, vecContents[1]); - EXPECT_DOUBLE_EQ(2.5, vecContents[2]); - EXPECT_DOUBLE_EQ(4.0, vecContents[3]); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[4]); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[5]); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[6]); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[7]); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[8]); - EXPECT_DOUBLE_EQ(9.5, vecContents[9]); -} - -TEST_F(PetscVectorElementTest, AssignElement) { - PetscVector::Element v1(&v, 1), v2(&v, 2); - v2 = v1 = 1.5; - VecAssemblyBegin(v); - VecAssemblyEnd(v); - PetscScalar* vecContents; - VecGetArray(v, &vecContents); - EXPECT_DOUBLE_EQ(1.5, vecContents[1]); - EXPECT_DOUBLE_EQ(1.5, vecContents[2]); -} - -TEST_F(PetscVectorElementTest, AssignAdd) { - PetscVector::Element v1(&v, 1), v2(&v, 2), v3(&v, 3), v3b(&v, 3), v9(&v, 9); - v1 += 1.5; - v2 += 2.5; - v3 += 3.5; - v3b += 4.0; - v9 += 9.5; - VecAssemblyBegin(v); - VecAssemblyEnd(v); - PetscScalar* vecContents; - VecGetArray(v, &vecContents); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[0]); - EXPECT_DOUBLE_EQ(2.5, vecContents[1]); - EXPECT_DOUBLE_EQ(3.5, vecContents[2]); - EXPECT_DOUBLE_EQ(8.5, vecContents[3]); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[4]); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[5]); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[6]); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[7]); - EXPECT_DOUBLE_EQ(defaultVal, vecContents[8]); - EXPECT_DOUBLE_EQ(10.5, vecContents[9]); -} - -TEST_F(PetscVectorElementTest, ConvertToBoutReal) { - PetscVector::Element v1(&v, 1); - BoutReal val = v1; - EXPECT_DOUBLE_EQ(defaultVal, val); -} - ///////////////// Test PetscMatrixElement ///////////////// class PetscMatrixElementTest : public ::testing::Test { diff --git a/tests/unit/include/bout/test_petsc_vector.cxx b/tests/unit/include/bout/test_petsc_vector.cxx index 101fb9480d..c478557ff4 100644 --- a/tests/unit/include/bout/test_petsc_vector.cxx +++ b/tests/unit/include/bout/test_petsc_vector.cxx @@ -36,11 +36,9 @@ class PetscVectorTest : public FakeMeshFixture { IndexerPtr indexer; PetscVectorTest() - : FakeMeshFixture(), field(bout::globals::mesh), + : FakeMeshFixture(), field(1.5, bout::globals::mesh), stencil(squareStencil(bout::globals::mesh)), indexer(std::make_shared>(bout::globals::mesh, stencil)) { - field.allocate(); - field = 1.5; PetscErrorPrintf = PetscErrorPrintfNone; } @@ -124,7 +122,8 @@ TYPED_TEST(PetscVectorTest, CopyAssignment) { SCOPED_TRACE("CopyAssignment"); PetscVector vector(this->field, this->indexer); PetscVector copy = vector; - Vec *vectorPtr = vector.get(), *copyPtr = copy.get(); + Vec* vectorPtr = vector.get(); + Vec* copyPtr = copy.get(); EXPECT_NE(vectorPtr, copyPtr); testVectorsEqual(vectorPtr, copyPtr); } @@ -139,18 +138,37 @@ TYPED_TEST(PetscVectorTest, MoveAssignment) { EXPECT_EQ(vectorPtr, movedPtr); } +TYPED_TEST(PetscVectorTest, SetElement) { + SCOPED_TRACE("FieldAssignment"); + PetscVector vector(this->field, this->indexer); + const TypeParam val(-10.); + + BOUT_FOR(index, val.getRegion("RGN_ALL")) { vector(index) = val[index]; } + vector.assemble(); + + Vec* vectorPtr = vector.get(); + PetscScalar* vecContents = nullptr; + PetscInt size = 0; + VecGetArray(*vectorPtr, &vecContents); + VecGetLocalSize(*vectorPtr, &size); + ASSERT_EQ(size, this->field.size()); + TypeParam result = vector.toField(); + BOUT_FOR(i, this->field.getRegion("RGN_NOY")) { EXPECT_EQ(result[i], val[i]); } +} + // Test getting elements TYPED_TEST(PetscVectorTest, TestGetElements) { PetscVector vector(this->field, this->indexer); BOUT_FOR(i, this->field.getRegion("RGN_NOBNDRY")) { vector(i) = (2.5 * this->field[i] - 1.0); } + vector.assemble(); + TypeParam result = vector.toField(); Vec* rawvec = vector.get(); - PetscScalar* vecContents; + PetscScalar* vecContents = nullptr; VecAssemblyBegin(*rawvec); VecAssemblyEnd(*rawvec); VecGetArray(*rawvec, &vecContents); - TypeParam result = vector.toField(); BOUT_FOR(i, this->field.getRegion("RGN_NOBNDRY")) { EXPECT_EQ(result[i], 2.5 * this->field[i] - 1.0); } @@ -165,19 +183,6 @@ TYPED_TEST(PetscVectorTest, TestGetElementsConst) { } } -// Test assemble -TYPED_TEST(PetscVectorTest, TestAssemble) { - PetscVector vector(this->field, this->indexer); - Vec* rawvec = vector.get(); - const PetscInt i = 4; - const PetscScalar r = 3.141592; - VecSetValues(*rawvec, 1, &i, &r, INSERT_VALUES); - vector.assemble(); - PetscScalar* vecContents; - VecGetArray(*rawvec, &vecContents); - ASSERT_EQ(vecContents[i], r); -} - #ifdef PETSC_USE_DEBUG // Test trying to get an element from an uninitialised vector @@ -201,14 +206,18 @@ TYPED_TEST(PetscVectorTest, TestGetOutOfBounds) { } #endif // CHECKLEVEL >= 3 -// Test trying to use both INSERT_VALUES and ADD_VALUES TYPED_TEST(PetscVectorTest, TestMixedSetting) { PetscVector vector(this->field, this->indexer); - typename TypeParam::ind_type i = *(this->field.getRegion("RGN_NOBNDRY").begin()); - typename TypeParam::ind_type j(i.ind + 1); + typename TypeParam::ind_type index1 = *(this->field.getRegion("RGN_NOBNDRY").begin()); + typename TypeParam::ind_type index2(index1.ind + 1); const PetscScalar r = 3.141592; - vector(i) = r; - EXPECT_THROW(vector(j) += r, BoutException); + vector(index1) = r; + vector(index2) += r; + vector.assemble(); + PetscScalar* vecContents = nullptr; + VecGetArray(*(vector.get()), &vecContents); + ASSERT_EQ(vecContents[index1.ind], r); + ASSERT_EQ(vecContents[index2.ind], this->field[index2] + r); } // Test destroy diff --git a/tests/unit/include/bout/test_region.cxx b/tests/unit/include/bout/test_region.cxx index f13fe8bd78..8776dad59a 100644 --- a/tests/unit/include/bout/test_region.cxx +++ b/tests/unit/include/bout/test_region.cxx @@ -262,7 +262,7 @@ TEST_F(RegionTest, regionLoopAllSection) { const auto& region = mesh->getRegion3D("RGN_ALL"); int count = 0; - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { BOUT_FOR_OMP(i, region, for reduction(+:count)) { ++count; @@ -274,11 +274,29 @@ TEST_F(RegionTest, regionLoopAllSection) { EXPECT_EQ(count, nmesh); } +TEST_F(RegionTest, regionIntersection) { + auto& region1 = mesh->getRegion3D("RGN_ALL"); + + auto& region2 = mesh->getRegion3D("RGN_NOBNDRY"); + + const int nmesh = RegionTest::nx * RegionTest::ny * RegionTest::nz; + + EXPECT_EQ(region1.size(), nmesh); + EXPECT_GT(region1.size(), region2.size()); + + const auto& region3 = intersection(region1, region2); + + EXPECT_EQ(region2.size(), region3.size()); + // Ensure this did not change + EXPECT_EQ(region1.size(), nmesh); + EXPECT_EQ(mesh->getRegion3D("RGN_ALL").size(), nmesh); +} + TEST_F(RegionTest, regionLoopNoBndrySection) { const auto& region = mesh->getRegion3D("RGN_NOBNDRY"); int count = 0; - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { BOUT_FOR_OMP(i, region, for reduction(+:count)) { ++count; @@ -295,7 +313,7 @@ TEST_F(RegionTest, regionLoopAllInner) { const auto& region = mesh->getRegion3D("RGN_ALL"); Field3D a{0.}; - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { BOUT_FOR_INNER(i, region) { a[i] = 1.0; } } @@ -313,7 +331,7 @@ TEST_F(RegionTest, regionLoopNoBndryInner) { const auto& region = mesh->getRegion3D("RGN_NOBNDRY"); Field3D a{0.}; - BOUT_OMP(parallel) + BOUT_OMP_PERF(parallel) { BOUT_FOR_INNER(i, region) { a[i] = 1.0; } } @@ -1101,36 +1119,27 @@ TEST_F(RegionTest, regionGetStatsEmpty) { } TEST(RegionIndexConversionTest, Ind3DtoInd2D) { - // This could just be: - // EXPECT_FALSE(std::is_convertible::value()); - // but requires C++14 - bool convert = std::is_convertible::value; - EXPECT_FALSE(convert); + EXPECT_FALSE((std::is_convertible_v)); } TEST(RegionIndexConversionTest, Ind2DtoInd3D) { - bool convert = std::is_convertible::value; - EXPECT_FALSE(convert); + EXPECT_FALSE((std::is_convertible_v)); } TEST(RegionIndexConversionTest, Ind2Dtoint) { - bool convert = std::is_convertible::value; - EXPECT_FALSE(convert); + EXPECT_FALSE((std::is_convertible_v)); } TEST(RegionIndexConversionTest, Ind3Dtoint) { - bool convert = std::is_convertible::value; - EXPECT_FALSE(convert); + EXPECT_FALSE((std::is_convertible_v)); } TEST(RegionIndexConversionTest, inttoInd2D) { - bool convert = std::is_convertible::value; - EXPECT_FALSE(convert); + EXPECT_FALSE((std::is_convertible_v)); } TEST(RegionIndexConversionTest, inttoInd3D) { - bool convert = std::is_convertible::value; - EXPECT_FALSE(convert); + EXPECT_FALSE((std::is_convertible_v)); } TEST(RegionIndex2DTest, MemberSize) { diff --git a/tests/unit/include/bout/test_stencil.cxx b/tests/unit/include/bout/test_stencil.cxx index 851abe957b..033a865154 100644 --- a/tests/unit/include/bout/test_stencil.cxx +++ b/tests/unit/include/bout/test_stencil.cxx @@ -11,8 +11,7 @@ template class IndexOffsetStructTests : public ::testing::Test { public: IndexOffsetStructTests() { - zero = T(0, std::is_same::value ? 1 : 5, - std::is_same::value ? 1 : 7); + zero = T(0, std::is_same_v ? 1 : 5, std::is_same_v ? 1 : 7); } IndexOffset noOffset; @@ -128,15 +127,15 @@ TYPED_TEST(IndexOffsetStructTests, AddToIndex) { offset4 = {2, 3, -2}; EXPECT_EQ(this->zero + offset1, this->zero.xp()); EXPECT_EQ(offset1 + this->zero, this->zero.xp()); - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { EXPECT_EQ(this->zero + offset2, this->zero.yp(2)); EXPECT_EQ(offset2 + this->zero, this->zero.yp(2)); } - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { EXPECT_EQ(this->zero + offset3, this->zero.zp(11)); EXPECT_EQ(offset3 + this->zero, this->zero.zp(11)); } - if (std::is_same::value) { + if constexpr (std::is_same_v) { EXPECT_EQ(this->zero + offset4, this->zero.xp(2).yp(3).zm(2)); EXPECT_EQ(offset4 + this->zero, this->zero.xp(2).yp(3).zm(2)); } @@ -146,13 +145,13 @@ TYPED_TEST(IndexOffsetStructTests, SubtractFromIndex) { IndexOffset offset1 = {1, 0, 0}, offset2 = {0, 2, 0}, offset3 = {0, 0, 11}, offset4 = {2, 3, -2}; EXPECT_EQ(this->zero - offset1, this->zero.xm()); - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { EXPECT_EQ(this->zero - offset2, this->zero.ym(2)); } - if (!std::is_same::value) { + if constexpr (!std::is_same_v) { EXPECT_EQ(this->zero - offset3, this->zero.zm(11)); } - if (std::is_same::value) { + if constexpr (std::is_same_v) { EXPECT_EQ(this->zero - offset4, this->zero.zp(2).xm(2).ym(3)); } } @@ -162,8 +161,7 @@ class StencilUnitTests : public ::testing::Test { public: WithQuietOutput all{output}; StencilUnitTests() { - zero = T(0, std::is_same::value ? 1 : 5, - std::is_same::value ? 1 : 7); + zero = T(0, std::is_same_v ? 1 : 5, std::is_same_v ? 1 : 7); for (int i = 0; i < static_cast(sizes.size()); i++) { std::vector> part; for (int j = 0; j < sizes[i]; j++) { diff --git a/tests/unit/include/bout/test_traits.cxx b/tests/unit/include/bout/test_traits.cxx index 98f0c542ad..10becb1551 100644 --- a/tests/unit/include/bout/test_traits.cxx +++ b/tests/unit/include/bout/test_traits.cxx @@ -10,34 +10,34 @@ TEST(BoutTraitsTest, IsField) { using namespace bout::utils; - static_assert(is_Field::value, "is_Field should be true"); - static_assert(is_Field::value, "is_Field should be true"); - static_assert(is_Field::value, "is_Field should be true"); - static_assert(is_Field::value, "is_Field should be true"); + static_assert(is_Field_v, "is_Field should be true"); + static_assert(is_Field_v, "is_Field should be true"); + static_assert(is_Field_v, "is_Field should be true"); + static_assert(is_Field_v, "is_Field should be true"); } TEST(BoutTraitsTest, IsField2D) { using namespace bout::utils; - static_assert(!is_Field2D::value, "is_Field2D should be false"); - static_assert(is_Field2D::value, "is_Field2D should be true"); - static_assert(!is_Field2D::value, "is_Field2D should be false"); - static_assert(!is_Field2D::value, "is_Field2D should be false"); + static_assert(!is_Field2D_v, "is_Field2D should be false"); + static_assert(is_Field2D_v, "is_Field2D should be true"); + static_assert(!is_Field2D_v, "is_Field2D should be false"); + static_assert(!is_Field2D_v, "is_Field2D should be false"); } TEST(BoutTraitsTest, IsField3D) { using namespace bout::utils; - static_assert(!is_Field3D::value, "is_Field3D should be false"); - static_assert(!is_Field3D::value, "is_Field3D should be false"); - static_assert(is_Field3D::value, "is_Field3D should be true"); - static_assert(!is_Field3D::value, "is_Field3D should be false"); + static_assert(!is_Field3D_v, "is_Field3D should be false"); + static_assert(!is_Field3D_v, "is_Field3D should be false"); + static_assert(is_Field3D_v, "is_Field3D should be true"); + static_assert(!is_Field3D_v, "is_Field3D should be false"); } TEST(BoutTraitsTest, IsFieldPerp) { using namespace bout::utils; - static_assert(!is_FieldPerp::value, "is_FieldPerp should be false"); - static_assert(!is_FieldPerp::value, "is_FieldPerp should be false"); - static_assert(!is_FieldPerp::value, "is_FieldPerp should be false"); - static_assert(is_FieldPerp::value, "is_FieldPerp should be true"); + static_assert(!is_FieldPerp_v, "is_FieldPerp should be false"); + static_assert(!is_FieldPerp_v, "is_FieldPerp should be false"); + static_assert(!is_FieldPerp_v, "is_FieldPerp should be false"); + static_assert(is_FieldPerp_v, "is_FieldPerp should be true"); } namespace { @@ -84,50 +84,50 @@ auto example_function(T, U) -> ResultType { TEST(BoutTraitsTest, EnableIfFieldOverloads) { using namespace bout::utils; - static_assert(std::is_same(), - std::declval()))>::value, + static_assert(std::is_same_v(), + std::declval()))>, "EnableIfField should enable function_overloads for two Fields"); static_assert( - std::is_same(), - std::declval()))>::value, + std::is_same_v(), + std::declval()))>, "EnableIfField should disable one overload of function_overloads.\n" "This static_assert should fail if the `function_overloads(T, BoutReal)` template\n" "is commented out"); static_assert( - std::is_same(), - std::declval()))>::value, + std::is_same_v(), + std::declval()))>, "EnableIfField should pick the correct version of specific_function_overloads"); static_assert( - std::is_same(), - std::declval()))>::value, + std::is_same_v(), + std::declval()))>, "EnableIfField should pick the correct version of specific_function_overloads"); static_assert( - std::is_same(), std::declval()))>::value, + std::is_same_v(), + std::declval()))>, "EnableIfField should pick the correct version of specific_function_overloads"); } TEST(BoutTraitsTest, EnableIfFieldReturnType) { using namespace bout::utils; static_assert( - std::is_same(), - std::declval()))>::value, + std::is_same_v(), + std::declval()))>, "EnableIfField should return Field2D for two Field2Ds"); static_assert( - std::is_same(), - std::declval()))>::value, + std::is_same_v(), + std::declval()))>, "EnableIfField should return Field3D for a Field2D and a Field3D"); static_assert( - std::is_same(), - std::declval()))>::value, + std::is_same_v(), + std::declval()))>, "EnableIfField should return Field3D for a Field2D and a Field3D"); static_assert( - std::is_same(), - std::declval()))>::value, + std::is_same_v(), + std::declval()))>, "EnableIfField should return Field3D for a Field3D and a Field3D"); } diff --git a/tests/unit/include/test_derivs.cxx b/tests/unit/include/test_derivs.cxx index 5e62ec51ce..a6b8e43ef0 100644 --- a/tests/unit/include/test_derivs.cxx +++ b/tests/unit/include/test_derivs.cxx @@ -70,8 +70,7 @@ class DerivativesTest const BoutReal box_length{TWOPI / grid_size}; // Set all the variables for this direction - // In C++14 this can be the more explicit std::get() - switch (std::get<0>(GetParam())) { + switch (std::get(GetParam())) { case DIRECTION::X: nx = grid_size; dir = &Index::x; @@ -103,33 +102,32 @@ class DerivativesTest mesh->createDefaultRegions(); + using std::invoke; // Make the input and expected output fields - // Weird `(i.*dir)()` syntax here in order to call the direction method - // C++17 makes this nicer with std::invoke input = makeField( - [&](Index& i) { return std::sin((i.*dir)() * box_length); }, mesh); + [&](Index& i) { return std::sin(invoke(dir, i) * box_length); }, mesh); // Make the velocity field velocity = makeField([&](Index& UNUSED(i)) { return 2.0; }, mesh); // Get the expected result for this order of derivative - // Again, could be nicer in C++17 with std::get(GetParam()) - switch (std::get<1>(GetParam())) { + switch (std::get(GetParam())) { case DERIV::Standard: expected = makeField( - [&](Index& i) { return std::cos((i.*dir)() * box_length) * box_length; }, mesh); + [&](Index& i) { return std::cos(invoke(dir, i) * box_length) * box_length; }, + mesh); break; case DERIV::StandardSecond: expected = makeField( [&](Index& i) { - return -std::sin((i.*dir)() * box_length) * pow(box_length, 2); + return -std::sin(invoke(dir, i) * box_length) * pow(box_length, 2); }, mesh); break; case DERIV::StandardFourth: expected = makeField( [&](Index& i) { - return std::sin((i.*dir)() * box_length) * pow(box_length, 4); + return std::sin(invoke(dir, i) * box_length) * pow(box_length, 4); }, mesh); break; @@ -138,7 +136,9 @@ class DerivativesTest case DERIV::Upwind: case DERIV::Flux: expected = makeField( - [&](Index& i) { return 2.0 * std::cos((i.*dir)() * box_length) * box_length; }, + [&](Index& i) { + return 2.0 * std::cos(invoke(dir, i) * box_length) * box_length; + }, mesh); break; default: @@ -191,7 +191,7 @@ auto getMethodsForDirection(DERIV derivative_order, DIRECTION direction) auto methodDirectionTupleToString( const ::testing::TestParamInfo>& param) -> std::string { - return std::get<2>(param.param); + return std::get(param.param); } // Instantiate the test for X, Y, Z for first derivatives @@ -278,8 +278,8 @@ INSTANTIATE_TEST_SUITE_P(FluxZ, DerivativesTestAdvection, // single test, just instantiate it for each direction/order combination TEST_P(DerivativesTest, Sanity) { auto derivative = DerivativeStore::getInstance().getStandardDerivative( - std::get<2>(GetParam()), std::get<0>(GetParam()), STAGGER::None, - std::get<1>(GetParam())); + std::get(GetParam()), std::get(GetParam()), STAGGER::None, + std::get(GetParam())); Field3D result{mesh}; result.allocate(); @@ -292,8 +292,8 @@ TEST_P(DerivativesTest, Sanity) { // single test, just instantiate it for each direction/order combination TEST_P(DerivativesTestAdvection, Sanity) { auto derivative = DerivativeStore::getInstance().getFlowDerivative( - std::get<2>(GetParam()), std::get<0>(GetParam()), STAGGER::None, - std::get<1>(GetParam())); + std::get(GetParam()), std::get(GetParam()), STAGGER::None, + std::get(GetParam())); Field3D result{mesh}; result.allocate(); @@ -327,7 +327,7 @@ INSTANTIATE_TEST_SUITE_P(FirstZ, FirstDerivativesInterfaceTest, TEST_P(FirstDerivativesInterfaceTest, Sanity) { Field3D result; - switch (std::get<0>(GetParam())) { + switch (std::get(GetParam())) { case DIRECTION::X: result = bout::derivatives::index::DDX(input); break; @@ -363,7 +363,7 @@ INSTANTIATE_TEST_SUITE_P(Z, SecondDerivativesInterfaceTest, TEST_P(SecondDerivativesInterfaceTest, Sanity) { Field3D result; - switch (std::get<0>(GetParam())) { + switch (std::get(GetParam())) { case DIRECTION::X: result = bout::derivatives::index::D2DX2(input); break; @@ -399,7 +399,7 @@ INSTANTIATE_TEST_SUITE_P(Z, FourthDerivativesInterfaceTest, TEST_P(FourthDerivativesInterfaceTest, Sanity) { Field3D result; - switch (std::get<0>(GetParam())) { + switch (std::get(GetParam())) { case DIRECTION::X: result = bout::derivatives::index::D4DX4(input); break; @@ -437,7 +437,7 @@ INSTANTIATE_TEST_SUITE_P(Z, UpwindDerivativesInterfaceTest, TEST_P(UpwindDerivativesInterfaceTest, Sanity) { Field3D result; - switch (std::get<0>(GetParam())) { + switch (std::get(GetParam())) { case DIRECTION::X: result = bout::derivatives::index::VDDX(velocity, input); break; @@ -475,7 +475,7 @@ INSTANTIATE_TEST_SUITE_P(Z, FluxDerivativesInterfaceTest, TEST_P(FluxDerivativesInterfaceTest, Sanity) { Field3D result; - switch (std::get<0>(GetParam())) { + switch (std::get(GetParam())) { case DIRECTION::X: result = bout::derivatives::index::FDDX(velocity, input); break; diff --git a/tests/unit/mesh/data/test_gridfromoptions.cxx b/tests/unit/mesh/data/test_gridfromoptions.cxx index d2a038cb93..84f08ff47b 100644 --- a/tests/unit/mesh/data/test_gridfromoptions.cxx +++ b/tests/unit/mesh/data/test_gridfromoptions.cxx @@ -33,6 +33,8 @@ class GridFromOptionsTest : public ::testing::Test { output_progress.disable(); output_warn.disable(); options["f"] = expected_string; + options["n"] = 12; + options["r"] = 3.14; // modify mesh section in global options options["dx"] = "1."; @@ -116,10 +118,11 @@ TEST_F(GridFromOptionsTest, GetStringNone) { TEST_F(GridFromOptionsTest, GetInt) { int result{-1}; - int expected{3}; - EXPECT_TRUE(griddata->get(&mesh_from_options, result, "f")); - EXPECT_EQ(result, expected); + // The expression must not depend on x,y,z or t + EXPECT_THROW(griddata->get(&mesh_from_options, result, "f"), BoutException); + griddata->get(&mesh_from_options, result, "n"); + EXPECT_EQ(result, 12); } TEST_F(GridFromOptionsTest, GetIntNone) { @@ -132,9 +135,9 @@ TEST_F(GridFromOptionsTest, GetIntNone) { TEST_F(GridFromOptionsTest, GetBoutReal) { BoutReal result{-1.}; - BoutReal expected{3.}; + BoutReal expected{3.14}; - EXPECT_TRUE(griddata->get(&mesh_from_options, result, "f")); + EXPECT_TRUE(griddata->get(&mesh_from_options, result, "r")); EXPECT_EQ(result, expected); } diff --git a/tests/unit/mesh/test_boundary_factory.cxx b/tests/unit/mesh/test_boundary_factory.cxx index 6637e73711..b552f7629e 100644 --- a/tests/unit/mesh/test_boundary_factory.cxx +++ b/tests/unit/mesh/test_boundary_factory.cxx @@ -1,6 +1,7 @@ #include "gtest/gtest.h" #include "bout/boundary_factory.hxx" +#include "bout/boundary_op.hxx" #include "bout/boundary_region.hxx" #include "test_extras.hxx" diff --git a/tests/unit/src/test_bout++.cxx b/tests/unit/src/test_bout++.cxx index e5d5419dfc..6f22ad76aa 100644 --- a/tests/unit/src/test_bout++.cxx +++ b/tests/unit/src/test_bout++.cxx @@ -378,7 +378,7 @@ TEST(BoutInitialiseFunctions, SetRunStartInfo) { bout::experimental::setRunStartInfo(options); - auto run_section = options["run"]; + auto& run_section = options["run"]; ASSERT_TRUE(run_section.isSection()); EXPECT_TRUE(run_section.isSet("version")); diff --git a/tests/unit/sys/test_expressionparser.cxx b/tests/unit/sys/test_expressionparser.cxx index 00cb23c042..c4f0ebfcf3 100644 --- a/tests/unit/sys/test_expressionparser.cxx +++ b/tests/unit/sys/test_expressionparser.cxx @@ -379,9 +379,9 @@ TEST_F(ExpressionParserTest, BadBinaryOp) { TEST_F(ExpressionParserTest, AddBinaryOp) { // Add a synonym for multiply with a lower precedence than addition - parser.addBinaryOp('&', std::make_shared(nullptr, nullptr, '*'), 5); + parser.addBinaryOp('$', std::make_shared(nullptr, nullptr, '*'), 5); - auto fieldgen = parser.parseString("2 & x + 3"); + auto fieldgen = parser.parseString("2 $ x + 3"); EXPECT_EQ(fieldgen->str(), "(2*(x+3))"); for (auto x : x_array) { @@ -679,3 +679,38 @@ TEST_F(ExpressionParserTest, FuzzyFind) { EXPECT_EQ(first_CAPS_match->name, "multiply"); EXPECT_EQ(first_CAPS_match->distance, 1); } + +TEST_F(ExpressionParserTest, LogicalOR) { + EXPECT_DOUBLE_EQ(parser.parseString("1 | 0")->generate({}), 1.0); + EXPECT_DOUBLE_EQ(parser.parseString("0 | 1")->generate({}), 1.0); + EXPECT_DOUBLE_EQ(parser.parseString("1 | 1")->generate({}), 1.0); + EXPECT_DOUBLE_EQ(parser.parseString("0 | 0")->generate({}), 0.0); +} + +TEST_F(ExpressionParserTest, LogicalAND) { + EXPECT_DOUBLE_EQ(parser.parseString("1 & 0")->generate({}), 0.0); + EXPECT_DOUBLE_EQ(parser.parseString("0 & 1")->generate({}), 0.0); + EXPECT_DOUBLE_EQ(parser.parseString("1 & 1")->generate({}), 1.0); + EXPECT_DOUBLE_EQ(parser.parseString("0 & 0")->generate({}), 0.0); +} + +TEST_F(ExpressionParserTest, LogicalNOT) { + EXPECT_DOUBLE_EQ(parser.parseString("!0")->generate({}), 1.0); + EXPECT_DOUBLE_EQ(parser.parseString("!1")->generate({}), 0.0); +} + +TEST_F(ExpressionParserTest, LogicalNOTprecedence) { + // Should bind more strongly than all binary operators + EXPECT_DOUBLE_EQ(parser.parseString("!1 & 0")->generate({}), 0.0); + EXPECT_DOUBLE_EQ(parser.parseString("1 & !0")->generate({}), 1.0); +} + +TEST_F(ExpressionParserTest, CompareGT) { + EXPECT_DOUBLE_EQ(parser.parseString("1 > 0")->generate({}), 1.0); + EXPECT_DOUBLE_EQ(parser.parseString("3 > 5")->generate({}), 0.0); +} + +TEST_F(ExpressionParserTest, CompareLT) { + EXPECT_DOUBLE_EQ(parser.parseString("1 < 0")->generate({}), 0.0); + EXPECT_DOUBLE_EQ(parser.parseString("3 < 5")->generate({}), 1.0); +} diff --git a/tests/unit/sys/test_options.cxx b/tests/unit/sys/test_options.cxx index a357923053..dbb687880d 100644 --- a/tests/unit/sys/test_options.cxx +++ b/tests/unit/sys/test_options.cxx @@ -232,10 +232,9 @@ TEST_F(OptionsTest, GetBoolFromString) { EXPECT_EQ(value, true); + // "yes" is not an acceptable bool bool value2; - options.get("bool_key2", value2, false, false); - - EXPECT_EQ(value2, true); + EXPECT_THROW(options.get("bool_key2", value2, false, false), BoutException); } TEST_F(OptionsTest, DefaultValueBool) { @@ -327,7 +326,7 @@ TEST_F(OptionsTest, ValueUsed) { Options options; options["key1"] = 1; EXPECT_FALSE(options["key1"].valueUsed()); - MAYBE_UNUSED(const int value) = options["key1"]; + [[maybe_unused]] const int value = options["key1"]; EXPECT_TRUE(options["key1"].valueUsed()); } @@ -603,23 +602,23 @@ TEST_F(OptionsTest, OptionsMacroConstReference) { EXPECT_EQ(val, 42); } -/// Copy constructor copies value +/// Copy method copies value TEST_F(OptionsTest, CopyOption) { Options option1; option1 = 42; - Options option2(option1); + Options option2(option1.copy()); EXPECT_EQ(option2.as(), 42); } -/// Copy constructor makes independent copy +/// Copy method makes independent copy TEST_F(OptionsTest, CopyOptionDistinct) { Options option1; option1 = 42; - Options option2(option1); + Options option2(option1.copy()); option1.force(23); @@ -633,7 +632,7 @@ TEST_F(OptionsTest, CopySection) { option1["key"] = 42; // option1 now a section - Options option2(option1); + Options option2(option1.copy()); EXPECT_EQ(option2["key"].as(), 42); } @@ -644,7 +643,7 @@ TEST_F(OptionsTest, CopySectionParent) { option1["key"] = 42; - Options option2(option1); + Options option2(option1.copy()); EXPECT_TRUE(&option2["key"].parent() == &option2); } @@ -654,7 +653,7 @@ TEST_F(OptionsTest, AssignOption) { option1 = 42; - option2 = option1; + option2 = option1.copy(); EXPECT_EQ(option2.as(), 42); } @@ -664,7 +663,7 @@ TEST_F(OptionsTest, AssignSection) { option1["key"] = 42; - option2 = option1; + option2 = option1.copy(); EXPECT_EQ(option2["key"].as(), 42); EXPECT_TRUE(option2["key"].isValue()); @@ -676,7 +675,7 @@ TEST_F(OptionsTest, AssignSectionReplace) { option1["key"] = 42; option2["key"] = 23; - option2 = option1; + option2 = option1.copy(); EXPECT_EQ(option2["key"].as(), 42); } @@ -686,7 +685,7 @@ TEST_F(OptionsTest, AssignSectionParent) { option1["key"] = 42; - option2 = option1; + option2 = option1.copy(); EXPECT_TRUE(&option2["key"].parent() == &option2); } @@ -696,7 +695,7 @@ TEST_F(OptionsTest, AssignSubSection) { option1["key1"] = 42; - option2["key2"] = option1; + option2["key2"] = option1.copy(); EXPECT_EQ(option2["key2"]["key1"].as(), 42); } @@ -706,7 +705,7 @@ TEST_F(OptionsTest, AssignSubSectionParent) { option1["key1"] = 42; - option2["key2"] = option1; + option2["key2"] = option1.copy(); EXPECT_EQ(&option2["key2"].parent(), &option2); EXPECT_EQ(&option2["key2"]["key1"].parent(), &option2["key2"]); @@ -1043,7 +1042,7 @@ TEST_F(OptionsTest, DocStringNotCopied) { Options option; option = 32; - Options option2 = option; + Options option2 = option.copy(); int value = option2.doc("test value"); @@ -1246,17 +1245,17 @@ TEST_F(OptionsTest, GetUnused) { // This shouldn't count as unused option["section2"]["value5"].attributes["source"] = "Output"; - MAYBE_UNUSED(auto value1) = option["section1"]["value1"].as(); - MAYBE_UNUSED(auto value3) = option["section2"]["subsection1"]["value3"].as(); + [[maybe_unused]] auto value1 = option["section1"]["value1"].as(); + [[maybe_unused]] auto value3 = option["section2"]["subsection1"]["value3"].as(); Options expected_unused{{"section1", {{"value2", "hello"}}}, {"section2", {{"subsection1", {{"value4", 3.2}}}}}}; EXPECT_EQ(option.getUnused(), expected_unused); - MAYBE_UNUSED(auto value2) = option["section1"]["value2"].as(); - MAYBE_UNUSED(auto value4) = option["section2"]["subsection1"]["value4"].as(); - MAYBE_UNUSED(auto value5) = option["section2"]["value5"].as(); + [[maybe_unused]] auto value2 = option["section1"]["value2"].as(); + [[maybe_unused]] auto value4 = option["section2"]["subsection1"]["value4"].as(); + [[maybe_unused]] auto value5 = option["section2"]["value5"].as(); Options expected_empty{}; @@ -1334,8 +1333,8 @@ TEST_F(OptionsTest, CheckForUnusedOptions) { // This shouldn't count as unused option["section2"]["value5"].attributes["source"] = "Output"; - MAYBE_UNUSED(auto value1) = option["section1"]["value1"].as(); - MAYBE_UNUSED(auto value3) = option["section2"]["subsection1"]["value3"].as(); + [[maybe_unused]] auto value1 = option["section1"]["value1"].as(); + [[maybe_unused]] auto value3 = option["section2"]["subsection1"]["value3"].as(); EXPECT_THROW(bout::checkForUnusedOptions(option, "data", "BOUT.inp"), BoutException); } @@ -1361,8 +1360,7 @@ TEST_P(BoolTrueTestParametrized, BoolTrueFromString) { } INSTANTIATE_TEST_CASE_P(BoolTrueTests, BoolTrueTestParametrized, - ::testing::Values("y", "Y", "yes", "Yes", "yeS", "t", "true", "T", - "True", "tRuE", "1")); + ::testing::Values("true", "True", "1")); class BoolFalseTestParametrized : public OptionsTest, public ::testing::WithParamInterface {}; @@ -1376,8 +1374,7 @@ TEST_P(BoolFalseTestParametrized, BoolFalseFromString) { } INSTANTIATE_TEST_CASE_P(BoolFalseTests, BoolFalseTestParametrized, - ::testing::Values("n", "N", "no", "No", "nO", "f", "false", "F", - "False", "fAlSe", "0")); + ::testing::Values("false", "False", "0")); class BoolInvalidTestParametrized : public OptionsTest, public ::testing::WithParamInterface {}; @@ -1391,6 +1388,52 @@ TEST_P(BoolInvalidTestParametrized, BoolInvalidFromString) { } INSTANTIATE_TEST_CASE_P(BoolInvalidTests, BoolInvalidTestParametrized, - ::testing::Values("a", "B", "yellow", "Yogi", "test", "truelong", - "Tim", "2", "not", "No bool", "nOno", - "falsebuttoolong", "-1")); + ::testing::Values("yes", "no", "y", "n", "a", "B", "yellow", + "Yogi", "test", "truelong", "Tim", "2", "not", + "No bool", "nOno", "falsebuttoolong", "-1", + "1.1")); + +TEST_F(OptionsTest, BoolLogicalOR) { + ASSERT_TRUE(Options("true | false").as()); + ASSERT_TRUE(Options("false | true").as()); + ASSERT_TRUE(Options("true | true").as()); + ASSERT_FALSE(Options("false | false").as()); + ASSERT_TRUE(Options("true | false | true").as()); +} + +TEST_F(OptionsTest, BoolLogicalAND) { + ASSERT_FALSE(Options("true & false").as()); + ASSERT_FALSE(Options("false & true").as()); + ASSERT_TRUE(Options("true & true").as()); + ASSERT_FALSE(Options("false & false").as()); + ASSERT_FALSE(Options("true & false & true").as()); + + EXPECT_THROW(Options("true & 1.3").as(), BoutException); + EXPECT_THROW(Options("2 & false").as(), BoutException); +} + +TEST_F(OptionsTest, BoolLogicalNOT) { + ASSERT_FALSE(Options("!true").as()); + ASSERT_TRUE(Options("!false").as()); + ASSERT_FALSE(Options("!true & false").as()); + ASSERT_TRUE(Options("!(true & false)").as()); + ASSERT_TRUE(Options("true & !false").as()); + + EXPECT_THROW(Options("!2").as(), BoutException); + EXPECT_THROW(Options("!1.2").as(), BoutException); +} + +TEST_F(OptionsTest, BoolComparisonGT) { + ASSERT_TRUE(Options("2 > 1").as()); + ASSERT_FALSE(Options("2 > 3").as()); +} + +TEST_F(OptionsTest, BoolComparisonLT) { + ASSERT_FALSE(Options("2 < 1").as()); + ASSERT_TRUE(Options("2 < 3").as()); +} + +TEST_F(OptionsTest, BoolCompound) { + ASSERT_TRUE(Options("true & !false").as()); + ASSERT_TRUE(Options("2 > 1 & 2 < 3").as()); +} diff --git a/tests/unit/sys/test_options_netcdf.cxx b/tests/unit/sys/test_options_netcdf.cxx index b086043822..38c80ca58c 100644 --- a/tests/unit/sys/test_options_netcdf.cxx +++ b/tests/unit/sys/test_options_netcdf.cxx @@ -7,13 +7,14 @@ #include "gtest/gtest.h" #include "test_extras.hxx" +#include "test_tmpfiles.hxx" #include "bout/field3d.hxx" #include "bout/mesh.hxx" -#include "bout/options_netcdf.hxx" +#include "bout/options_io.hxx" -using bout::OptionsNetCDF; +using bout::OptionsIO; -#include +#include /// Global mesh namespace bout { @@ -25,11 +26,8 @@ extern Mesh* mesh; // Reuse the "standard" fixture for FakeMesh class OptionsNetCDFTest : public FakeMeshFixture { public: - OptionsNetCDFTest() : FakeMeshFixture() {} - ~OptionsNetCDFTest() override { std::remove(filename.c_str()); } - // A temporary filename - std::string filename{std::tmpnam(nullptr)}; + bout::testing::TempFile filename; WithQuietOutput quiet{output_info}; }; @@ -39,11 +37,11 @@ TEST_F(OptionsNetCDFTest, ReadWriteInt) { options["test"] = 42; // Write the file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read again - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_EQ(data["test"], 42); } @@ -54,11 +52,11 @@ TEST_F(OptionsNetCDFTest, ReadWriteString) { options["test"] = std::string{"hello"}; // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_EQ(data["test"], std::string("hello")); } @@ -69,11 +67,11 @@ TEST_F(OptionsNetCDFTest, ReadWriteField2D) { options["test"] = Field2D(1.0); // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); Field2D value = data["test"].as(bout::globals::mesh); @@ -87,11 +85,11 @@ TEST_F(OptionsNetCDFTest, ReadWriteField3D) { options["test"] = Field3D(2.4); // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); Field3D value = data["test"].as(bout::globals::mesh); @@ -106,11 +104,11 @@ TEST_F(OptionsNetCDFTest, Groups) { options["test"]["key"] = 42; // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_EQ(data["test"]["key"], 42); } @@ -121,11 +119,11 @@ TEST_F(OptionsNetCDFTest, AttributeInt) { options["test"].attributes["thing"] = 4; // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_EQ(data["test"].attributes["thing"].as(), 4); } @@ -136,11 +134,11 @@ TEST_F(OptionsNetCDFTest, AttributeBoutReal) { options["test"].attributes["thing"] = 3.14; // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_DOUBLE_EQ(data["test"].attributes["thing"].as(), 3.14); } @@ -151,11 +149,11 @@ TEST_F(OptionsNetCDFTest, AttributeString) { options["test"].attributes["thing"] = "hello"; // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_EQ(data["test"].attributes["thing"].as(), "hello"); } @@ -165,11 +163,11 @@ TEST_F(OptionsNetCDFTest, Field2DWriteCellCentre) { options["f2d"] = Field2D(2.0); // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_EQ(data["f2d"].attributes["cell_location"].as(), toString(CELL_CENTRE)); @@ -181,11 +179,11 @@ TEST_F(OptionsNetCDFTest, Field2DWriteCellYLow) { options["f2d"] = Field2D(2.0, mesh_staggered).setLocation(CELL_YLOW); // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_EQ(data["f2d"].attributes["cell_location"].as(), toString(CELL_YLOW)); @@ -197,11 +195,11 @@ TEST_F(OptionsNetCDFTest, Field3DWriteCellCentre) { options["f3d"] = Field3D(2.0); // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_EQ(data["f3d"].attributes["cell_location"].as(), toString(CELL_CENTRE)); @@ -213,11 +211,11 @@ TEST_F(OptionsNetCDFTest, Field3DWriteCellYLow) { options["f3d"] = Field3D(2.0, mesh_staggered).setLocation(CELL_YLOW); // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_EQ(data["f3d"].attributes["cell_location"].as(), toString(CELL_YLOW)); @@ -235,11 +233,11 @@ TEST_F(OptionsNetCDFTest, FieldPerpWriteCellCentre) { fperp.getMesh()->getXcomm(); // Write file - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } // Read file - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_EQ(data["fperp"].attributes["cell_location"].as(), toString(CELL_CENTRE)); @@ -252,10 +250,10 @@ TEST_F(OptionsNetCDFTest, VerifyTimesteps) { options["thing1"] = 1.0; options["thing1"].attributes["time_dimension"] = "t"; - OptionsNetCDF(filename).write(options); + OptionsIO::create(filename)->write(options); } - EXPECT_NO_THROW(OptionsNetCDF(filename).verifyTimesteps()); + EXPECT_NO_THROW(OptionsIO::create(filename)->verifyTimesteps()); { Options options; @@ -265,10 +263,11 @@ TEST_F(OptionsNetCDFTest, VerifyTimesteps) { options["thing2"] = 3.0; options["thing2"].attributes["time_dimension"] = "t"; - OptionsNetCDF(filename, OptionsNetCDF::FileMode::append).write(options); + OptionsIO::create({{"type", "netcdf"}, {"file", filename.string()}, {"append", true}}) + ->write(options); } - EXPECT_THROW(OptionsNetCDF(filename).verifyTimesteps(), BoutException); + EXPECT_THROW(OptionsIO::create(filename)->verifyTimesteps(), BoutException); } TEST_F(OptionsNetCDFTest, WriteTimeDimension) { @@ -278,10 +277,10 @@ TEST_F(OptionsNetCDFTest, WriteTimeDimension) { options["thing2"].assignRepeat(2.0, "t2"); // non-default // Only write non-default time dim - OptionsNetCDF(filename).write(options, "t2"); + OptionsIO::create(filename)->write(options, "t2"); } - Options data = OptionsNetCDF(filename).read(); + Options data = OptionsIO::create(filename)->read(); EXPECT_FALSE(data.isSet("thing1")); EXPECT_TRUE(data.isSet("thing2")); @@ -297,12 +296,12 @@ TEST_F(OptionsNetCDFTest, WriteMultipleTimeDimensions) { options["thing4_t2"].assignRepeat(2.0, "t2"); // non-default // Write the non-default time dim twice - OptionsNetCDF(filename).write(options, "t2"); - OptionsNetCDF(filename).write(options, "t2"); - OptionsNetCDF(filename).write(options, "t"); + OptionsIO::create(filename)->write(options, "t2"); + OptionsIO::create(filename)->write(options, "t2"); + OptionsIO::create(filename)->write(options, "t"); } - EXPECT_NO_THROW(OptionsNetCDF(filename).verifyTimesteps()); + EXPECT_NO_THROW(OptionsIO::create(filename)->verifyTimesteps()); } #endif // BOUT_HAS_NETCDF diff --git a/tests/unit/sys/test_optionsreader.cxx b/tests/unit/sys/test_optionsreader.cxx index 3bb71bb510..efd4c47a8a 100644 --- a/tests/unit/sys/test_optionsreader.cxx +++ b/tests/unit/sys/test_optionsreader.cxx @@ -1,4 +1,5 @@ #include "test_extras.hxx" +#include "test_tmpfiles.hxx" #include "bout/optionsreader.hxx" #include "gtest/gtest.h" @@ -6,7 +7,6 @@ #include "bout/output.hxx" #include "bout/utils.hxx" -#include #include #include #include @@ -28,8 +28,6 @@ class OptionsReaderTest : public ::testing::Test { // Make sure options singleton is clean Options::cleanup(); - - std::remove(filename.c_str()); } // Write cout to buffer instead of stdout @@ -39,7 +37,7 @@ class OptionsReaderTest : public ::testing::Test { WithQuietOutput quiet{output_info}; // A temporary filename - std::string filename{std::tmpnam(nullptr)}; + bout::testing::TempFile filename; }; TEST_F(OptionsReaderTest, BadFilename) { @@ -196,7 +194,7 @@ bool_key = false OptionsReader reader; Options* options = Options::getRoot(); - reader.read(options, filename); + reader.read(options, filename.string()); ASSERT_TRUE(options->isSet("flag")); @@ -236,7 +234,7 @@ bool_key = false TEST_F(OptionsReaderTest, ReadBadFile) { OptionsReader reader; Options* options = Options::getRoot(); - EXPECT_THROW(reader.read(options, filename), BoutException); + EXPECT_THROW(reader.read(options, filename.string()), BoutException); } TEST_F(OptionsReaderTest, ReadBadFileSectionIncomplete) { @@ -251,7 +249,7 @@ int_key = 34 OptionsReader reader; Options* options = Options::getRoot(); - EXPECT_THROW(reader.read(options, filename), BoutException); + EXPECT_THROW(reader.read(options, filename.string()), BoutException); }; TEST_F(OptionsReaderTest, ReadBadFileSectionEmptyName) { @@ -266,7 +264,7 @@ int_key = 34 OptionsReader reader; Options* options = Options::getRoot(); - EXPECT_THROW(reader.read(options, filename), BoutException); + EXPECT_THROW(reader.read(options, filename.string()), BoutException); }; TEST_F(OptionsReaderTest, WriteFile) { @@ -280,7 +278,7 @@ TEST_F(OptionsReaderTest, WriteFile) { Options* subsection2 = section1->getSection("subsection2"); subsection2->set("string_key", "BOUT++", "test"); - reader.write(options, filename); + reader.write(options, filename.string()); std::ifstream test_file(filename); std::stringstream test_buffer; @@ -297,7 +295,8 @@ TEST_F(OptionsReaderTest, WriteFile) { } TEST_F(OptionsReaderTest, WriteBadFile) { - std::string filename1 = filename + std::tmpnam(nullptr); + std::string file_in_nonexistent_dir = + bout::testing::test_directory() / "dir_that_doesnt_exist/some_filename"; OptionsReader reader; Options* options = Options::getRoot(); @@ -305,9 +304,7 @@ TEST_F(OptionsReaderTest, WriteBadFile) { Options* section1 = options->getSection("section1"); section1->set("int_key", 17, "test"); - EXPECT_THROW(reader.write(options, filename1), BoutException); - - std::remove(filename1.c_str()); + EXPECT_THROW(reader.write(options, file_in_nonexistent_dir), BoutException); } TEST_F(OptionsReaderTest, ReadEmptyString) { @@ -322,7 +319,7 @@ value = Options opt; OptionsReader reader; - reader.read(&opt, filename); + reader.read(&opt, filename.string()); std::string val = opt["value"]; EXPECT_TRUE(val.empty()); @@ -350,9 +347,9 @@ test6 = h2`+`:on`e-`more # Escape sequences in the middle test_file.close(); OptionsReader reader; - reader.read(Options::getRoot(), filename); + reader.read(Options::getRoot(), filename.string()); - auto options = Options::root()["tests"]; + auto& options = Options::root()["tests"]; EXPECT_EQ(options["test1"].as(), 3); EXPECT_EQ(options["test2"].as(), 15); @@ -376,7 +373,7 @@ some:value = 3 OptionsReader reader; - EXPECT_THROW(reader.read(Options::getRoot(), filename), BoutException); + EXPECT_THROW(reader.read(Options::getRoot(), filename.string()), BoutException); } TEST_F(OptionsReaderTest, ReadUnicodeNames) { @@ -396,9 +393,9 @@ twopi = 2 * π # Unicode symbol defined for pi test_file.close(); OptionsReader reader; - reader.read(Options::getRoot(), filename); + reader.read(Options::getRoot(), filename.string()); - auto options = Options::root()["tests"]; + auto& options = Options::root()["tests"]; EXPECT_EQ(options["結果"].as(), 8); EXPECT_DOUBLE_EQ(options["value"].as(), 1.3 * (1 + 3)); @@ -425,7 +422,7 @@ value = [a = 1, OptionsReader reader; reader.read(Options::getRoot(), filename.c_str()); - auto options = Options::root(); + auto& options = Options::root(); EXPECT_EQ(options["result"].as(), 6); EXPECT_EQ(options["value"].as(), 5); @@ -452,7 +449,7 @@ value = [a = 1, OptionsReader reader; reader.read(Options::getRoot(), filename.c_str()); - auto options = Options::root(); + auto& options = Options::root(); EXPECT_EQ(options["result"].as(), 6); EXPECT_EQ(options["value"].as(), 5); diff --git a/tests/unit/sys/test_output.cxx b/tests/unit/sys/test_output.cxx index 661e7bb1af..1338d9ce13 100644 --- a/tests/unit/sys/test_output.cxx +++ b/tests/unit/sys/test_output.cxx @@ -1,9 +1,9 @@ +#include "test_tmpfiles.hxx" #include "bout/boutexception.hxx" #include "bout/output.hxx" #include "bout/output_bout_types.hxx" #include "gtest/gtest.h" -#include #include // stdout redirection code from https://stackoverflow.com/a/4043813/2043465 @@ -19,8 +19,6 @@ class OutputTest : public ::testing::Test { buffer.str(""); // When done redirect cout to its old self std::cout.rdbuf(sbuf); - - std::remove(filename.c_str()); } // Write cout to buffer instead of stdout @@ -28,7 +26,7 @@ class OutputTest : public ::testing::Test { // Save cout's buffer here std::streambuf* sbuf; // A temporary filename - std::string filename{std::tmpnam(nullptr)}; + bout::testing::TempFile filename; }; TEST_F(OutputTest, JustStdOutCpp) { @@ -56,7 +54,7 @@ TEST_F(OutputTest, OpenFile) { std::string test_output = "To stdout and file\n"; - local_output.open(filename); + local_output.open(filename.string()); local_output << test_output; std::ifstream test_file(filename); @@ -73,7 +71,7 @@ TEST_F(OutputTest, JustPrint) { std::string test_output = "To stdout only\n"; - local_output.open(filename); + local_output.open(filename.string()); local_output.print(test_output); std::ifstream test_file(filename); @@ -92,7 +90,7 @@ TEST_F(OutputTest, DisableEnableStdout) { std::string file_and_stdout = "To stdout and file\n"; // Open temporary file and close stdout - local_output.open(filename); + local_output.open(filename.string()); local_output.disable(); local_output << file_only; @@ -219,7 +217,7 @@ TEST_F(OutputTest, ConditionalJustPrint) { std::string test_output = "To stdout only\n"; - local_output.open(filename); + local_output.open(filename.string()); local_output.print(test_output); std::ifstream test_file(filename); @@ -288,7 +286,7 @@ TEST_F(OutputTest, DummyJustPrint) { std::string test_output = "To stdout only\n"; - dummy.open(filename); + dummy.open(filename.string()); dummy.print(test_output); std::ifstream test_file(filename); diff --git a/tests/unit/sys/test_utils.cxx b/tests/unit/sys/test_utils.cxx index 0826a742de..747257bafc 100644 --- a/tests/unit/sys/test_utils.cxx +++ b/tests/unit/sys/test_utils.cxx @@ -693,10 +693,10 @@ void function_template(T) {} TEST(FunctionTraitsTest, ResultType) { using bout::utils::function_traits; - static_assert(std::is_same::result_type, int>::value, + static_assert(std::is_same_v::result_type, int>, "Wrong result_type for function_traits of a typedef"); static_assert( - std::is_same::result_type, int>::value, + std::is_same_v::result_type, int>, "Wrong result_type for function_traits of a function pointer"); static_assert( std::is_same)>::result_type, @@ -719,9 +719,8 @@ TEST(FunctionTraitsTest, NumberOfArgs) { TEST(FunctionTraitsTest, FirstArg) { using bout::utils::function_traits; - static_assert( - std::is_same::arg<0>::type, char>::value, - "Wrong first argument type for function_traits of a typedef"); + static_assert(std::is_same_v::arg<0>::type, char>, + "Wrong first argument type for function_traits of a typedef"); static_assert(std::is_same::arg<0>::type, double>::value, "Wrong first argument type for function_traits of a function pointer"); @@ -730,10 +729,10 @@ TEST(FunctionTraitsTest, FirstArg) { int>::value, "Wrong first argument type for function_traits of a template function"); - static_assert(std::is_same::arg_t<0>, char>::value, + static_assert(std::is_same_v::arg_t<0>, char>, "Wrong first argument type for function_traits of a typedef using arg_t"); static_assert( - std::is_same::arg_t<0>, double>::value, + std::is_same_v::arg_t<0>, double>, "Wrong first argument type for function_traits of a function pointer using arg_t"); static_assert( std::is_same)>::arg_t<0>, @@ -743,10 +742,10 @@ TEST(FunctionTraitsTest, FirstArg) { TEST(FunctionTraitsTest, SecondArg) { using bout::utils::function_traits; - static_assert(std::is_same::arg<1>::type, int>::value, + static_assert(std::is_same_v::arg<1>::type, int>, "Wrong second argument type for function_traits of a typedef"); static_assert( - std::is_same::arg_t<1>, int>::value, + std::is_same_v::arg_t<1>, int>, "Wrong second argument type for function_traits of a typedef using arg_t"); } diff --git a/tests/unit/test_extras.cxx b/tests/unit/test_extras.cxx index a4c51ac3c4..491dd189fc 100644 --- a/tests/unit/test_extras.cxx +++ b/tests/unit/test_extras.cxx @@ -3,11 +3,6 @@ #include -// Need to provide a redundant declaration because C++ -constexpr int FakeMeshFixture::nx; -constexpr int FakeMeshFixture::ny; -constexpr int FakeMeshFixture::nz; - ::testing::AssertionResult IsSubString(const std::string& str, const std::string& substring) { if (str.find(substring) != std::string::npos) { diff --git a/tests/unit/test_extras.hxx b/tests/unit/test_extras.hxx index f0868ddf49..700b977ac8 100644 --- a/tests/unit/test_extras.hxx +++ b/tests/unit/test_extras.hxx @@ -8,6 +8,7 @@ #include #include +#include "bout/boundary_region.hxx" #include "bout/boutcomm.hxx" #include "bout/coordinates.hxx" #include "bout/field3d.hxx" @@ -51,13 +52,13 @@ inline std::ostream& operator<<(std::ostream& out, const SpecificInd& index) } /// Helpers to get the type of a Field as a string -auto inline getFieldType(MAYBE_UNUSED(const Field2D& field)) -> std::string { +auto inline getFieldType([[maybe_unused]] const Field2D& field) -> std::string { return "Field2D"; } -auto inline getFieldType(MAYBE_UNUSED(const Field3D& field)) -> std::string { +auto inline getFieldType([[maybe_unused]] const Field3D& field) -> std::string { return "Field3D"; } -auto inline getFieldType(MAYBE_UNUSED(const FieldPerp& field)) -> std::string { +auto inline getFieldType([[maybe_unused]] const FieldPerp& field) -> std::string { return "FieldPerp"; } @@ -232,8 +233,9 @@ public: RangeIterator iterateBndryUpperInnerY() const override { return RangeIterator(); } void addBoundary(BoundaryRegion* region) override { boundaries.push_back(region); } std::vector getBoundaries() override { return boundaries; } - std::vector getBoundariesPar() override { - return std::vector(); + std::vector> + getBoundariesPar(BoundaryParType UNUSED(type)) override { + return std::vector>(); } BoutReal GlobalX(int jx) const override { return jx; } BoutReal GlobalY(int jy) const override { return jy; } @@ -332,14 +334,14 @@ class FakeGridDataSource : public GridDataSource { public: FakeGridDataSource() {} /// Constructor setting values which can be fetched from this source - FakeGridDataSource(Options& values) : values(values) {} + FakeGridDataSource(const Options& values) : values(values.copy()) {} /// Take an rvalue (e.g. initializer list), convert to lvalue and delegate constructor FakeGridDataSource(Options&& values) : FakeGridDataSource(values) {} bool hasVar(const std::string& UNUSED(name)) override { return false; } - bool get(MAYBE_UNUSED(Mesh* m), std::string& sval, const std::string& name, + bool get([[maybe_unused]] Mesh* m, std::string& sval, const std::string& name, const std::string& def = "") override { if (values[name].isSet()) { sval = values[name].as(); @@ -348,7 +350,7 @@ public: sval = def; return false; } - bool get(MAYBE_UNUSED(Mesh* m), int& ival, const std::string& name, + bool get([[maybe_unused]] Mesh* m, int& ival, const std::string& name, int def = 0) override { if (values[name].isSet()) { ival = values[name].as(); @@ -357,7 +359,7 @@ public: ival = def; return false; } - bool get(MAYBE_UNUSED(Mesh* m), BoutReal& rval, const std::string& name, + bool get([[maybe_unused]] Mesh* m, BoutReal& rval, const std::string& name, BoutReal def = 0.0) override { if (values[name].isSet()) { rval = values[name].as(); @@ -394,15 +396,15 @@ public: return false; } - bool get(MAYBE_UNUSED(Mesh* m), MAYBE_UNUSED(std::vector& var), - MAYBE_UNUSED(const std::string& name), MAYBE_UNUSED(int len), - MAYBE_UNUSED(int def) = 0, Direction = GridDataSource::X) override { + bool get([[maybe_unused]] Mesh* m, [[maybe_unused]] std::vector& var, + [[maybe_unused]] const std::string& name, [[maybe_unused]] int len, + [[maybe_unused]] int def = 0, Direction = GridDataSource::X) override { throw BoutException("Not Implemented"); return false; } - bool get(MAYBE_UNUSED(Mesh* m), MAYBE_UNUSED(std::vector& var), - MAYBE_UNUSED(const std::string& name), MAYBE_UNUSED(int len), - MAYBE_UNUSED(int def) = 0, + bool get([[maybe_unused]] Mesh* m, [[maybe_unused]] std::vector& var, + [[maybe_unused]] const std::string& name, [[maybe_unused]] int len, + [[maybe_unused]] int def = 0, Direction UNUSED(dir) = GridDataSource::X) override { throw BoutException("Not Implemented"); return false; diff --git a/tests/unit/test_tmpfiles.hxx b/tests/unit/test_tmpfiles.hxx new file mode 100644 index 0000000000..35d7579df2 --- /dev/null +++ b/tests/unit/test_tmpfiles.hxx @@ -0,0 +1,41 @@ +#pragma once + +#include +#include +#include + +namespace bout::testing { + +/// Return a temporary directory that definitely exists +inline auto test_directory() { + auto test_dir = std::filesystem::temp_directory_path() / "bout_tests"; + create_directory(test_dir); + return test_dir; +} + +/// Create a uniquely named temporary file that is automatically cleaned up +class TempFile { + static int current_count() { + static int count{0}; + return count++; + } + + std::filesystem::path filename{test_directory() + / fmt::format("tempfile_{}", current_count())}; + +public: + TempFile() = default; + TempFile(const TempFile&) = delete; + TempFile(TempFile&&) = delete; + TempFile& operator=(const TempFile&) = delete; + TempFile& operator=(TempFile&&) = delete; + + ~TempFile() { std::filesystem::remove(filename); } + + // Enable conversions to std::string / const char* + operator std::string() const { return filename.string(); } + auto c_str() const { return filename.c_str(); } + auto string() const { return filename.string(); } +}; + +} // namespace bout::testing diff --git a/tools/archiving/sdctools/sdclib/sdclib.c b/tools/archiving/sdctools/sdclib/sdclib.c index f7db255a47..7294cc0791 100644 --- a/tools/archiving/sdctools/sdclib/sdclib.c +++ b/tools/archiving/sdctools/sdclib/sdclib.c @@ -34,8 +34,6 @@ #include "sdclib.h" -//#define DEBUG - #define DEFAULT_IFRAME 10 #define DEFAULT_ORDER 4 diff --git a/tools/pylib/_boutpp_build/CMakeLists.txt b/tools/pylib/_boutpp_build/CMakeLists.txt index 6b88986a28..3be2a5d2aa 100644 --- a/tools/pylib/_boutpp_build/CMakeLists.txt +++ b/tools/pylib/_boutpp_build/CMakeLists.txt @@ -25,7 +25,7 @@ bout_python_maybe_error(${Cython_FOUND} Cython) find_package(Bash) bout_python_maybe_error(${Bash_FOUND} Bash) -execute_process(COMMAND ${Python_EXECUTABLE} -c "import jinja2" +execute_process(COMMAND ${Python3_EXECUTABLE} -c "import jinja2" RESULT_VARIABLE jinja2_FOUND) if (jinja2_FOUND EQUAL 0) # We have jinja2 - all good @@ -33,7 +33,7 @@ else() bout_python_maybe_error(OFF jinja2) endif() -execute_process(COMMAND ${Python_EXECUTABLE} -c "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX')[:-3])" +execute_process(COMMAND ${Python3_EXECUTABLE} -c "import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX')[:-3])" RESULT_VARIABLE PYTHON_WORKING OUTPUT_VARIABLE PYTHON_EXT_SUFFIX OUTPUT_STRIP_TRAILING_WHITESPACE @@ -73,7 +73,7 @@ foreach(file IN LISTS files) #message(FATAL_ERROR "${gen} ${src}/${file}.jinja") add_custom_command(OUTPUT ${gen} COMMAND ${CMAKE_COMMAND} -E make_directory ${tar} - COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${tar}/..:\${PYTHONPATH} ${Python_EXECUTABLE} generate.py ${file}.jinja ${gen} + COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${tar}/..:\${PYTHONPATH} ${Python3_EXECUTABLE} generate.py ${file}.jinja ${gen} DEPENDS ${src}/${file}.jinja DEPENDS ${src}/helper.py DEPENDS ${src}/resolve_enum_inv.pyx.jinja @@ -93,8 +93,7 @@ endforeach() add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/libboutpp.cpp COMMAND ${CMAKE_COMMAND} -E copy boutpp.pyx libboutpp.pyx - COMMAND ${Python_EXECUTABLE} -m cython libboutpp.pyx --cplus -3 -X binding=True -X embedsignature=True - COMMENT "Cythonizing python interface" + COMMAND ${Python3_EXECUTABLE} -m cython libboutpp.pyx --cplus -3 -X binding=True -X embedsignature=True WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${boutpp_depends} ) @@ -120,5 +119,6 @@ install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/boutpp.py DESTINATION ${CMAKE_INSTALL_PYTHON_SITEARCH}/boutpp/ RENAME __init__.py ) + target_link_libraries(boutpp${PYTHON_EXT_SUFFIX} bout++) -target_include_directories(boutpp${PYTHON_EXT_SUFFIX} PRIVATE $ ${Numpy_INCLUDE_DIRS} ${Python_INCLUDE_DIRS}) +target_include_directories(boutpp${PYTHON_EXT_SUFFIX} PRIVATE $ ${Numpy_INCLUDE_DIRS} ${Python3_INCLUDE_DIRS}) diff --git a/tools/pylib/_boutpp_build/bout_options.pxd b/tools/pylib/_boutpp_build/bout_options.pxd index ba5e64c8e3..365e08bcc7 100644 --- a/tools/pylib/_boutpp_build/bout_options.pxd +++ b/tools/pylib/_boutpp_build/bout_options.pxd @@ -8,20 +8,11 @@ cdef extern from "boutexception_helper.hxx": cdef void raise_bout_py_error() -cdef extern from "bout/options_netcdf.hxx" namespace "bout": - cdef void writeDefaultOutputFile(); +cdef extern from "bout/options_io.hxx" namespace "bout": cdef void writeDefaultOutputFile(Options& options); - cppclass OptionsNetCDF: - enum FileMode: - replace - append - OptionsNetCDF() except +raise_bout_py_error - OptionsNetCDF(string filename) except +raise_bout_py_error - OptionsNetCDF(string filename, FileMode mode) except +raise_bout_py_error - OptionsNetCDF(const OptionsNetCDF&); - OptionsNetCDF(OptionsNetCDF&&); - OptionsNetCDF& operator=(const OptionsNetCDF&); - OptionsNetCDF& operator=(OptionsNetCDF&&); + cppclass OptionsIO: + @staticmethod + OptionsIO * create(string filename) Options read(); void write(const Options& options); void write(const Options& options, string time_dim); @@ -52,6 +43,7 @@ cdef extern from "bout/options.hxx": void get(string, double&, double) void get(string, bool&, bool) void cleanCache() + void setConditionallyUsed() cdef extern from "bout/optionsreader.hxx": diff --git a/tools/pylib/_boutpp_build/boutcpp.pxd.jinja b/tools/pylib/_boutpp_build/boutcpp.pxd.jinja index c94fd14a17..8f838b864c 100644 --- a/tools/pylib/_boutpp_build/boutcpp.pxd.jinja +++ b/tools/pylib/_boutpp_build/boutcpp.pxd.jinja @@ -5,7 +5,7 @@ from libcpp.memory cimport unique_ptr from libcpp.string cimport string cimport resolve_enum as benum -from bout_options cimport Options, OptionsReader, OptionsNetCDF, writeDefaultOutputFile +from bout_options cimport Options, OptionsReader, OptionsIO, writeDefaultOutputFile cdef extern from "boutexception_helper.hxx": cdef void raise_bout_py_error() @@ -148,10 +148,10 @@ cdef extern from "bout/physicsmodel.hxx": ctypedef void (*Method)(void *param, void *user_data) cdef extern from "helper.h": cppclass PythonModel(PhysicsModel): - int rhs(double t) + int rhs(double t) except +raise_bout_py_error void pyinit() void free() - void solve() + void solve() except +raise_bout_py_error Solver * getSolver() void set_rhs_func(PythonModelCallback*) void set_init_func(PythonModelCallback*) diff --git a/tools/pylib/_boutpp_build/boutpp.pyx.jinja b/tools/pylib/_boutpp_build/boutpp.pyx.jinja index 657e2f28c1..9aedbb291a 100644 --- a/tools/pylib/_boutpp_build/boutpp.pyx.jinja +++ b/tools/pylib/_boutpp_build/boutpp.pyx.jinja @@ -583,9 +583,9 @@ cdef class {{ field.field_type }}: {% endfor %} def __dealloc__(self): - self.__boutpp_dealloc() + self._boutpp_dealloc() - def __boutpp_dealloc(self): + def _boutpp_dealloc(self): if self.isSelfOwned and self.cobj != NULL: del self.cobj self.cobj = NULL @@ -645,9 +645,9 @@ cdef class {{ vec }}: def __dealloc__(self): - self.__boutpp_dealloc() + self._boutpp_dealloc() - def __boutpp_dealloc(self): + def _boutpp_dealloc(self): if self.isSelfOwned and self.cobj != NULL: del self.cobj self.cobj=NULL @@ -742,9 +742,9 @@ cdef class Mesh: return msh def __dealloc__(self): - self.__boutpp_dealloc() + self._boutpp_dealloc() - def __boutpp_dealloc(self): + def _boutpp_dealloc(self): if self.cobj and self.isSelfOwned: del self.cobj self.cobj = NULL @@ -850,9 +850,9 @@ cdef class Coordinates: {% endfor %} def __dealloc__(self): - self.__boutpp_dealloc() + self._boutpp_dealloc() - def __boutpp_dealloc(self): + def _boutpp_dealloc(self): if self.cobj and self.isSelfOwned: del self.cobj self.cobj = NULL @@ -931,9 +931,9 @@ cdef class FieldFactory: checkInit() cobj=< c.FieldFactory*>0 def __dealloc__(self): - self.__boutpp_dealloc() + self._boutpp_dealloc() - def __boutpp_dealloc(self): + def _boutpp_dealloc(self): if self.cobj != NULL: del self.cobj self.cobj = NULL @@ -965,9 +965,9 @@ cdef class PythonModelCallback: self.cobj = new c.PythonModelCallback(callback, method) def __dealloc__(self): - self.__boutpp_dealloc() + self._boutpp_dealloc() - def __boutpp_dealloc(self): + def _boutpp_dealloc(self): if self.cobj: del self.cobj self.cobj = NULL @@ -1037,12 +1037,12 @@ cdef class PhysicsModelBase(object): self.cmodel.set_init_func(self.callbackinit) def __dealloc__(self): - if hasattr(self, "__boutpp_dealloc"): - self.__boutpp_dealloc() + if hasattr(self, "_boutpp_dealloc"): + self._boutpp_dealloc() else: - PhysicsModelBase.__boutpp_dealloc(self) + PhysicsModelBase._boutpp_dealloc(self) - def __boutpp_dealloc(self): + def _boutpp_dealloc(self): if self.cmodel != 0: self.cmodel.free() del self.cmodel @@ -1123,8 +1123,8 @@ class PhysicsModel(PhysicsModelBase): def __dealloc__(self): super(PhysicsModel,self).__dealloc__() - def __boutpp_dealloc(self): - super(PhysicsModel,self).__boutpp_dealloc() + def _boutpp_dealloc(self): + super(PhysicsModel,self)._boutpp_dealloc() cdef extern from "bout/bout.hxx": int BoutInitialise(int&, char **&) except +raise_bout_py_error @@ -1204,13 +1204,14 @@ def finalise(): PythonModelCallback) for obj in objects: if isinstance(obj, ourClasses): - if hasattr(obj, "__boutpp_dealloc"): - obj.__boutpp_dealloc() + if hasattr(obj, "_boutpp_dealloc"): + obj._boutpp_dealloc() else: for ourClass in ourClasses: if isinstance(obj, ourClass): - ourClass.__boutpp_dealloc(obj) - break + if hasattr(ourClass, "_boutpp_dealloc"): + ourClass._boutpp_dealloc(obj) + break del objects # Actually finalise if wasInit: @@ -1715,15 +1716,23 @@ cdef class Options: opt.get(key, ret_str, default_) return ret_str.decode() + def setConditionallyUsed(self): + """Set the attribute "conditionally used" to be true for \p options + and all its children/sections, causing `Options::getUnused` to + assume those options have been used. This is useful to ignore + options when checking for typos etc. + """ + cdef c.Options* opt = self.cobj + opt.setConditionallyUsed() + def __dealloc__(self): - self.__boutpp_dealloc() + self._boutpp_dealloc() - def __boutpp_dealloc(self): + def _boutpp_dealloc(self): if self.isSelfOwned and self.cobj != NULL: del self.cobj self.cobj = NULL - def writeDefaultOutputFile(options: Options): c.writeDefaultOutputFile(deref(options.cobj)) diff --git a/tools/pylib/post_bout/ListDict.py b/tools/pylib/post_bout/ListDict.py deleted file mode 100644 index f500825651..0000000000 --- a/tools/pylib/post_bout/ListDict.py +++ /dev/null @@ -1,61 +0,0 @@ -from __future__ import print_function -import sys -import os - -try: - boutpath = os.environ["BOUT_TOP"] - pylibpath = boutpath + "/pylib" - pbpath = pylibpath + "/post_bout" - boutdatapath = pylibpath + "/boutdata" - boututilpath = pylibpath + "/boututils" - - allpath = [boutpath, pylibpath, pbpath, boutdatapath, boututilpath] - [sys.path.append(elem) for elem in allpath] -except: - print("meh") - -import numpy as np - - -def ListDictKey(input, key): - # given a key and a list of dictionaries this method returns an ordered - # list of requested key values - output = [] - for x in input: - try: - # print x[key] - output.append(x[key]) - except: - print("Key not found") - return 1 - - return output - - -def ListDictFilt(input, key, valuelist): - # given a key,value pair and a list of dictionaries this - # method returns an ordered list of dictionaries where (dict(key)==value) = True - # http://stackoverflow.com/questions/5762643/how-to-filter-list-of-dictionaries-with-matching-values-for-a-given-key - try: - x = copyf(input, key, valuelist) - return x - except: - return [] - - -def copyf(dictlist, key, valuelist): - return [dictio for dictio in dictlist if dictio[key] in valuelist] - - -# def subset(obj): -# #def __init__(self,alldb,key,valuelist,model=False): -# selection = ListDictFilt(obj.mode_db,obj.key,valuelist) -# if len(selection) !=0: -# LinRes.__init__(obj,selection) -# self.skey = key -# if model==True: -# self.model() -# else: -# LinRes.__init__(self,alldb) -# if model==True: -# self.model() diff --git a/tools/pylib/post_bout/__init__.py b/tools/pylib/post_bout/__init__.py deleted file mode 100644 index 069ae3e85b..0000000000 --- a/tools/pylib/post_bout/__init__.py +++ /dev/null @@ -1,95 +0,0 @@ -from __future__ import print_function -from __future__ import absolute_import - -################################################## -# BOUT++ data package -# -# Routines for examining simulation results for BOUT++ -# -################################################## - -print("Loading BOUT++ post processing routines") - -# Load routines from separate files -import sys -import os - -try: - boutpath = os.environ["BOUT_TOP"] - pylibpath = boutpath + "/tools/pylib" - boutdatapath = pylibpath + "/boutdata" - boututilpath = pylibpath + "/boututils" - allpath = [boutpath, pylibpath, boutdatapath, boututilpath] - [sys.path.append(elem) for elem in allpath] - print(sys.path) - - # sys.path.append('/home/cryosphere/BOUT/tools/pylib') - # sys.path.append('/home/cryosphere/BOUT/tools/pylib/boutdata') - # sys.path.append('/home/cryosphere/BOUT/tools/pylib/boututils') - - print("in post_bout/__init__.py") - - import matplotlib - - matplotlib.use("pdf") # savemovie must be called as a diff. sesssion - - import gobject - import numpy as np -except ImportError: - print("can't find the modules I need, you fail") - sys.exit() # no point in going on - - -# import some bout specific modules -try: - import boutdata - import boututils -except: - print("can't find bout related modules, you fail") - -# import some home-brewed modules - - -# create some aliases - - -try: - from read_grid import read_grid -except: - print("Sorry, no read_grid") - -try: - from .read_inp import parse_inp, read_inp, read_log, metadata -except: - print("Sorry no parse_inp") - -try: - from .read_cxx import read_cxx, get_evolved_cxx, no_comment_cxx -except: - print("Sorry no read_cxx") - -try: - from post_bout import save, read -except: - print("Sorry, no show") - -try: - from .basic_info import basic_info, fft_info -except: - print("Sorry, no basic_info") - -try: - from .pb_corral import corral, LinRes, subset -except: - print("No corral") - -try: - from . import ListDict -except: - print("No ListDict") - -try: - # from rotate_mp import rotate - from rotate2 import rotate -except: - print("No rotate") diff --git a/tools/pylib/post_bout/basic_info.py b/tools/pylib/post_bout/basic_info.py deleted file mode 100644 index 563bfe6e98..0000000000 --- a/tools/pylib/post_bout/basic_info.py +++ /dev/null @@ -1,421 +0,0 @@ -from __future__ import print_function -from __future__ import division -from builtins import zip -from builtins import range -from past.utils import old_div - -# basic_info return some statistical averages and harmonic info -import numpy as np -import math - - -def basic_info(data, meta, rescale=True, rotate=False, user_peak=0, nonlinear=None): - print("in basic_info") - # from . import read_grid,parse_inp,read_inp,show - - dims = data.shape - ndims = len(dims) - - mxg = meta["MXG"]["v"] - - if ndims == 4: - nt, nx, ny, nz = data.shape - print(nt, nx, ny) - else: - print("something with dimesions") - - dc = ( - data.mean(1).mean(1).mean(1) - ) # there MUST be a way to indicate all axis at once - amp = abs(data).max(1).max(1).max(1) - dt = meta["dt"]["v"] - - if rescale: - amp_o = amp - dc - fourDamp = np.repeat(amp_o, nx * ny * nz) - fourDamp = fourDamp.reshape(nt, nx, ny, nz) - dc_n = old_div(dc, amp_o) - data_n = old_div(data, fourDamp) - - print(data.shape) - dfdt = np.gradient(data)[0] - dfdt = abs(dfdt).max(1).max(1).max(1) - - ave = {"amp": amp, "dc": dc, "amp_o": amp_o, "dfdt": dfdt} - - else: - print("no rescaling") - ave = {"amp": amp, "dc": dc} - - if nonlinear is not None: # add nonlinear part if user provides - nl = abs(nonlinear[:, mxg : -1.0 * mxg, :, :]).max(1).max(1).max(1) - nl_norm = (old_div(nl, dfdt)) * dt - - ave["nl"] = nl - ave["nl_norm"] = nl_norm - - if rotate: - print("rotate stuff") - # will need to provide some grid geometry to do this one - else: - print("or not") - - # let's identify the dominant modes, for now at every [t,x] slice - # if the data set is too large we can average over x - peaks_db = fft_info( - data, user_peak, meta=meta - ) # Nt X Nx X (# of loc. max) list of dict - - # print peaks[0]['gamma'] - return peaks_db, ave - - -def fft_info( - data, - user_peak, - dimension=[3, 4], - rescale=False, - wavelet=False, - show=False, - meta=0, - edgefix=False, -): - import numpy as np - import math - - print("in fft_inf0") - - dims = data.shape - ndims = len(dims) - - if ndims == 4: - nt, nx, ny, nz = data.shape - print(data.shape) - else: - print("something with dimesions") - - # data2 = data - # if edgefix: - # data2 = np.zeros((nt,nx,ny+1,nz+1)) - - # for t in range(nt): - # for x in range(nx): - # temp = np.append(data[t,x,:,:],[data[t,x,0,:]],0) - # data2[t,x,:,:] = np.append(temp, - # np.transpose([temp[:,0]]),1) - - # dt, k labels for the revelant dimensions - - dt = meta["dt"]["v"] - dz = meta["dz"] - # IC = meta['IC'] - ky_max = old_div(ny, 2) - kz_max = old_div(nz, 2) - amp = abs(data).max(2).max(2) # nt x nx - - print("dt: ", dt) - - # print data[0,2,:,:] - - IC = amp[0, :].max() # intial condition, set - print(IC) - - fft_data = np.fft.fft2(data)[ - :, :, 0:ky_max, 0:kz_max - ] # by default the last 2 dimensions - - power = fft_data.conj() * fft_data - # print power[0].max(), (IC*(ky_max)*(kz_max))**2 - - cross_pow = old_div((fft_data * (np.roll(fft_data, 1, axis=0)).conj()), (ny * nz)) - - if rescale: - fft_data_n = np.fft.fft2(data_n)[:, :, 0:ky_max, 0:kz_max] - pow_n = np.sqrt((fft_data_n.conj() * fft_data_n).real) - - peaks = [[[] for i in range(nx)] for j in range(nt)] # a list of dictionaries - peaks_db = [] - - peak_hist = [[0 for i in range(kz_max)] for j in range(ky_max)] # a 2d bin array - - # for now using a lame 2x loop method - - if user_peak != 0: - for mem in user_peak: - print(mem) - peak_hist[int(mem[0])][int(mem[1])] = abs( - power.mean(0).mean(0)[int(mem[0]), int(mem[1])] - ) - - # floor = ((IC*(kz_max*ky_max))**2)/10000 - - else: - for t in range(nt): - for x in range(nx): - peaks[t][x] = local_maxima( - power[t, x, :, :], 0, floor=(IC * (kz_max * ky_max)) ** 2 - ) - for p in peaks[t][ - x - ]: # looping over each returned peakset at some fixed t,x pair - peak_hist[p["y_i"]][ - p["z_i"] - ] += 1 # average across t and x, at least exclude pad - floor = 0 - - # this array is usefull for determining what the dominant modes are - # but we want to retain the option of observing how the amplitude - # of any give harmonic varies in space - - peak_hist = np.array(peak_hist) - - # let's find the top N overall powerfull harmnonics - net_peak = local_maxima(peak_hist, user_peak, bug=False) - - print("net_peak: ", net_peak, user_peak != 0) - # dom_mode = [{'amp':[],'amp_n':[],'phase':[],'freq':[],'gamma':[]} for x in net_peak] - dom_mode_db = [] - - Bp = meta["Bpxy"]["v"][:, old_div(ny, 2)] - B = meta["Bxy"]["v"][:, old_div(ny, 2)] - Bt = meta["Btxy"]["v"][:, old_div(ny, 2)] - - rho_s = meta["rho_s"]["v"] - - L_z = old_div(meta["L_z"], rho_s) - # L_z = - L_y = meta["lpar"] # already normalized earlier in read_inp.py - L_norm = old_div(meta["lbNorm"], rho_s) - - hthe0_n = 1e2 * meta["hthe0"]["v"] / rho_s # no x dep - hthe0_n_x = old_div(L_y, (2 * np.pi)) # no x dep - - print("L_z,Ly: ", L_z, L_y) - - # if user provides the harmo nic info overide the found peaks - - # thi is where all the good stuff is picked up - - # look at each mode annd pull out some usefull linear measures - for i, p in enumerate(net_peak): - # print i,p['y_i'],p['z_i'],fft_data.shape,fft_data[:,:,p['y_i'],p['z_i']].shape - - amp = ( - old_div(np.sqrt(power[:, :, p["y_i"], p["z_i"]]), (kz_max * ky_max)) - ).real - - # print (np.angle(fft_data[:,:,p['y_i'],p['z_i']],deg=False)).real - - phase = -np.array( - np.gradient( - np.squeeze(np.angle(fft_data[:, :, p["y_i"], p["z_i"]], deg=False)) - )[0].real - ) # nt x nx - - gamma_instant = np.array(np.gradient(np.log(np.squeeze(amp)))[0]) - - # loop over radaii - phasenew = [] - gammanew = [] - from scipy.interpolate import interp2d, interp1d - from scipy import interp - - gamma_t = np.transpose(gamma_instant) - for i, phase_r in enumerate(np.transpose(phase)): - gamma_r = gamma_t[i] - jumps = np.where(abs(phase_r) > old_div(np.pi, 32)) - # print jumps - if len(jumps[0]) != 0: - all_pts = np.array(list(range(0, nt))) - good_pts = (np.where(abs(phase_r) < old_div(np.pi, 3)))[0] - # print good_pts,good_pts - # f = interp1d(good_pts,phase_r[good_pts],fill_value=.001) - # print max(all_pts), max(good_pts) - # phasenew.append(f(all_pts)) - try: - phase_r = interp(all_pts, good_pts, phase_r[good_pts]) - gamma_r = interp(all_pts, good_pts, gamma_r[good_pts]) - except: - "no phase smoothing" - phasenew.append(phase_r) - gammanew.append(gamma_r) - - phase = old_div(np.transpose(phasenew), dt) - - gamma_i = old_div(np.transpose(gammanew), dt) - - amp_n = ( - old_div(np.sqrt(power[:, :, p["y_i"], p["z_i"]]), (kz_max * ky_max * amp)) - ).real - # amp_n = dom_mode[i]['amp_n'] #nt x nx - - # let just look over the nx range - # lnamp = np.log(amp[nt/2:,2:-2]) - try: - lnamp = np.log(amp[old_div(nt, 2) :, :]) - except: - print("some log(0) stuff in basic_info") - - t = dt * np.array(list(range(nt))) # dt matters obviouslyww - r = np.polyfit(t[old_div(nt, 2) :], lnamp, 1, full=True) - - gamma_est = r[0][0] # nx - f0 = np.exp(r[0][1]) # nx - res = r[1] - pad = [0, 0] - # gamma_est = np.concatenate([pad,gamma_est,pad]) - # f0 = np.concatenate([pad,f0,pad]) - # res = np.concatenate([pad,res,pad]) - - # sig = res/np.sqrt((x['nt']-2)) - sig = np.sqrt(old_div(res, (nt - 2))) - # sig0 = sig*np.sqrt(1/(x['nt'])+ ) # who cares - sig1 = sig * np.sqrt(old_div(1.0, (nt * t.var()))) - nt = np.array(nt) - print("shapes ", nt.shape, nt, lnamp.shape, res.shape, gamma_est) - # print r - res = 1 - old_div(res, (nt * lnamp.var(0))) # nx - res[0:2] = 0 - res[-2:] = 0 - - gamma = [gamma_est, sig1, f0, res] - - # gamma_est2 = np.gradient(amp)[0]/(amp[:,:]*dt) - # gamma_w = np.gradient(gamma_est2)[0] - - # gamma_i = np.abs(gamma_w).argmin(0) #index of the minimum for any given run - # for j in range(nx): - # gamma_w[0:max([gamma_i[j],nt/3]),j] = np.average(gamma_w)*100000.0 - - freq = np.array( - weighted_avg_and_std(phase[-10:, :], weights=np.ones(phase[-10:, :].shape)) - ) - - # gamma = weighted_avg_and_std( - # gamma_est2[-5:,:],weights=np.ones(gamma_est2[-5:,:].shape)) - - k = [ - [p["y_i"], p["z_i"]], - [2 * math.pi * float(p["y_i"]) / L_y, 2 * math.pi * p["z_i"] / L_z], - ] - # L_y is normalized - - # simple k def, works in drift-instability fine - # k = [[p['y_i'],p['z_i']], - # [(B/Bp)**-1*2*math.pi*float(p['y_i'])/(L_y),(B/Bp)*2*math.pi*p['z_i']/L_z]] - - # k_r = [[p['y_i'],p['z_i']], - # [(Bp/B)*2*math.pi*float(p['y_i'])/(L_y), - # (B/Bp)*2*math.pi*p['z_i']/L_z]] - - k_r = [ - [p["y_i"], p["z_i"]], - [ - 2 * math.pi * float(p["y_i"]) / (L_y), - (old_div(B, Bp)) * 2 * math.pi * p["z_i"] / L_z - + (old_div(Bt, B)) * 2 * math.pi * float(p["y_i"]) / (L_y), - ], - ] - - # revised - # k_r = [[p['y_i'],p['z_i']], - # [2*math.pi*float(p['y_i'])/(L_y), - # (Bp/B)*2*math.pi*p['z_i']/L_z - # - (Bt/Bp)*2*math.pi*float(p['y_i'])/(L_y)]] - # revised - - # what I think is the most general one, works in drift-instability again - # seems to work for Bz only helimak, now trying Bp = Bt - # k = [[p['y_i'],p['z_i']], - # [((Bp/B)*float(p['y_i'])/(hthe0_n)) + - # 2*np.pi*p['z_i']*np.sqrt(1-(Bp/B)**2)/L_z, - # 2*math.pi*p['z_i']/L_norm - - # float(p['y_i'])*np.sqrt(1-(Bp/B)**2)/(hthe0_n)]] - # k = [[p['y_i'],p['z_i']], - # [((Bp/B)*float(p['y_i'])/(hthe0_n)), - # 2*math.pi*p['z_i']/L_norm]] - # BOTH SEEM TO PRODOCE SAME RESULTS - - # k = [[p['y_i'],p['z_i']], - # [(float(p['y_i'])/(hthe0_n_x)), - # 2*math.pi*float(p['z_i'])/L_norm]] - - dom_mode_db.append( - { - "modeid": i, - "k": k[1], - "gamma": gamma, - "freq": freq, - "amp": amp, - "amp_n": amp_n, - "phase": phase, - "mn": k[0], - "nt": nt, - "k_r": k_r[1], - "gamma_i": gamma_i, - } - ) - - return dom_mode_db - - -# return a 2d array fof boolean values, a very simple boolian filter -def local_maxima(array2d, user_peak, index=False, count=4, floor=0, bug=False): - from operator import itemgetter, attrgetter - - if user_peak == 0: - where = ( - (array2d >= np.roll(array2d, 1, 0)) - & (array2d >= np.roll(array2d, -1, 0)) - & (array2d >= np.roll(array2d, 0, 1)) - & (array2d >= np.roll(array2d, 0, -1)) - & (array2d >= old_div(array2d.max(), 5.0)) - & (array2d > floor * np.ones(array2d.shape)) - & (array2d >= array2d.mean()) - ) - else: # some simpler filter if user indicated some modes - where = array2d > floor - - # ignore the lesser local maxima, throw out anything with a ZERO - if bug == True: - print(array2d, array2d[where.nonzero()], where.nonzero()[0]) - - peaks = list(zip(where.nonzero()[0], where.nonzero()[1], array2d[where.nonzero()])) - - peaks = sorted(peaks, key=itemgetter(2), reverse=True) - - if len(peaks) > count and user_peak == 0: - peaks = peaks[0:count] - - keys = ["y_i", "z_i", "amp"] - - peaks = [dict(list(zip(keys, peaks[x]))) for x in range(len(peaks))] - - return peaks - # return np.array(peak_dic) - - -def weighted_avg_and_std(values, weights): - """ - Returns the weighted average and standard deviation. - - values, weights -- Numpy ndarrays with the same shape. - """ - - if len(values.shape) == 2: - average = np.average(values, 0) # , weights=weights) - variance = old_div( - ( - np.inner( - weights.transpose(), ((values - average) ** 2).transpose() - ).diagonal() - ), - weights.sum(0), - ) - else: - average = np.average(values, weights=weights) - variance = old_div( - np.dot(weights, (values - average) ** 2), weights.sum() - ) # Fast and numerically precise - - return [average, variance] diff --git a/tools/pylib/post_bout/grate2.py b/tools/pylib/post_bout/grate2.py deleted file mode 100644 index 5157863cc2..0000000000 --- a/tools/pylib/post_bout/grate2.py +++ /dev/null @@ -1,52 +0,0 @@ -from __future__ import print_function -from builtins import range - -### -# compute average growth rate bout variable f and plane y -# prints value in plane y and total average -# optional tind excludes initial 'tind' time steps -# Note it masks the values != Inf -### -import numpy as np -from boutdata.collect import collect -from boututils.moment_xyzt import moment_xyzt - - -def avgrate(p, y=None, tind=None): - if tind is None: - tind = 0 - - rmsp_f = moment_xyzt(p, "RMS").rms - - ni = np.shape(rmsp_f)[1] - nj = np.shape(rmsp_f)[2] - - growth = np.zeros((ni, nj)) - - with np.errstate(divide="ignore"): - for i in range(ni): - for j in range(nj): - growth[i, j] = np.gradient(np.log(rmsp_f[tind::, i, j]))[-1] - - d = np.ma.masked_array(growth, np.isnan(growth)) - - # masked arrays - # http://stackoverflow.com/questions/5480694/numpy-calculate-averages-with-nans-removed - - print("Total average growth rate= ", np.mean(np.ma.masked_array(d, np.isinf(d)))) - if y is not None: - print( - "Growth rate in plane", - y, - "= ", - np.mean(np.ma.masked_array(growth[:, y], np.isnan(growth[:, y]))), - ) - - -# test -if __name__ == "__main__": - path = "/Users/brey/BOUT/bout/examples/elm-pb/data" - - data = collect("P", path=path) - - avgrate(data, 32) diff --git a/tools/pylib/post_bout/pb_corral.py b/tools/pylib/post_bout/pb_corral.py deleted file mode 100644 index df9a9b00b6..0000000000 --- a/tools/pylib/post_bout/pb_corral.py +++ /dev/null @@ -1,540 +0,0 @@ -# note - these commands are only run by default in interactive mode -from __future__ import print_function -from __future__ import absolute_import -from __future__ import division -from builtins import filter -from builtins import range -from past.utils import old_div -from builtins import object -import os -import sys - -try: - boutpath = os.environ["BOUT_TOP"] - pylibpath = boutpath + "tools/pylib" - pbpath = pylibpath + "/post_bout" - boutdatapath = pylibpath + "/boutdata" - boututilpath = pylibpath + "/boututils" - - allpath = [boutpath, pylibpath, pbpath, boutdatapath, boututilpath] - [sys.path.append(elem) for elem in allpath] - -except: - print("unable to append needed .py files") - -sys.path.append("/usr/local/pylib") - -import post_bout as post_bout -from .ListDict import ListDictKey, ListDictFilt -from .read_inp import parse_inp, read_inp, read_log -from .basic_info import weighted_avg_and_std -from .read_cxx import read_cxx, findlowpass - - -import os -import numpy as np -import pickle -import subprocess - - -def corral( - cached=True, refresh=False, debug=False, IConly=1, logname="status.log", skew=False -): - print("in corral") - log = read_log(logname=logname) - # done = log['done'] - runs = log["runs"] # a list of all directories, we need this, - # only need 'runs' if the simulation is done - - current = log["current"] # always return the last data_dir - - print(log) - print("current:", current) - - if refresh == True: - for i, path in enumerate(runs): - print(i, path) - a = post_bout.save(path=path, IConly=IConly) # re post-process a run - - elif ( - cached == False - ): # if all the ind. simulation pkl files are in place skip this part - a = post_bout.save(path=current) # save to current dir - # here is really where you shoudl write to status.log - # write_log('status.log', - cached = True - - # if done: - - all_ave = [] - all_modes = [] - print("last_one: ") - for i, val in enumerate(runs): - print(val) - mode_db, ave_db = post_bout.read(path=val) - # alldata.append(array) - all_modes.append(mode_db) - all_ave.append(ave_db) - - # build the end database - - # remove the read in pickle - - # return alldb - def islist(input): - return isinstance(input, list) - - all_modes = list(filter(islist, all_modes)) - # all_ave = filter(islist,all_ave) - - # alldb = sum(alldb,[]) - # alldata = np.array(alldata) - all_modes = sum(all_modes, []) - - nt = [] - for mode in all_modes: - nt.append(len(mode["amp"])) - nt = [max(nt)] - - nt = nt[0] - t = list(range(nt)) - i = 0 - - if debug: - return all_modes, all_ave - else: - return LinRes(all_modes) - - -class LinRes(object): - def __init__(self, all_modes): - self.mode_db = all_modes - self.db = all_modes - # self.ave_db = all_ave - - alldb = self.db - # self.modekeys = data[0]['fields']['Ni']['modes'][0].keys() - # print len(alldb) - - self.meta = np.array(ListDictKey(self.db, "meta"))[0] - - self.keys = list((self.mode_db)[0].keys()) - # self.avekeys = data[0]['fields']['Ni']['ave'].keys() - - # self.nrun = len(alldb) #number of runs - - self.path = np.array(ListDictKey(self.db, "path")) - self.cxx = [] - self.maxN = [] - - self.ave = np.array(ListDictKey(alldb, "ave")) - - # [self.cxx.append(read_cxx(path=elem,boutcxx='2fluid.cxx.ref')) for elem in self.path] - # [self.maxN.append(findlowpass(elem)) for elem in self.cxx] - [ - self.cxx.append(read_cxx(path=elem, boutcxx="physics_code.cxx.ref")) - for elem in self.path - ] - - self.maxZ = np.array(ListDictKey(alldb, "maxZ")) - self.maxN = self.maxZ - # self.maxN = findlowpass(self.cxx) #low pass filt from .cxx - - self.nx = np.array(ListDictKey(alldb, "nx"))[0] - self.ny = np.array(ListDictKey(alldb, "ny"))[0] - self.nz = np.array(ListDictKey(alldb, "nz"))[0] - - # self.nt = int(data[0]['meta']['NOUT']['v']+1) - self.Rxy = np.array(ListDictKey(alldb, "Rxy")) - self.Rxynorm = np.array(ListDictKey(alldb, "Rxynorm")) - self.nt = np.array(ListDictKey(alldb, "nt")) - - self.dt = np.array(ListDictKey(alldb, "dt")) - self.nfields = np.array(ListDictKey(alldb, "nfields")) - - self.field = np.array(ListDictKey(alldb, "field")) - - self.k = np.array(ListDictKey(alldb, "k")) - self.k_r = np.array(ListDictKey(alldb, "k_r")) - - self.mn = np.array(ListDictKey(alldb, "mn")) - - # return ListDictKey(alldb,'phase') - - # self.phase = np.array(ListDictKey(alldb,'phase')) - self.phase = ListDictKey(alldb, "phase") - - # self.amp= np.array(ListDictKey(alldb,'amp')) - # self.amp_n=np.array(ListDictKey(alldb,'amp_n')) - # self.dc= [] - # self.freq = np.array(ListDictKey(alldb,'k')) - # self.gamma = np.array(ListDictKey(alldb,'gamma')) - - self.amp = ListDictKey(alldb, "amp") - self.amp_n = ListDictKey(alldb, "amp_n") - self.dc = [] - # self.freq = np.array(ListDictKey(alldb,'k')) - self.gamma = np.array(ListDictKey(alldb, "gamma")) - self.gamma_i = np.array(ListDictKey(alldb, "gamma_i")) - - self.freq = np.array(ListDictKey(alldb, "freq")) - - self.IC = np.array(ListDictKey(alldb, "IC")) - self.dz = np.array(ListDictKey(alldb, "dz")) - self.meta["dz"] = np.array(list(set(self.dz).union())) - - self.nmodes = self.dz.size - - self.MN = np.array(ListDictKey(alldb, "MN")) - # self.MN = np.float32(self.mn) - # self.MN[:,1] = self.mn[:,1]/self.dz - self.nrun = len(set(self.path).union()) - self.L = np.array(ListDictKey(alldb, "L")) - # self.C_s = - self.modeid = np.array(ListDictKey(alldb, "modeid")) - - self.trans = np.array(ListDictKey(alldb, "transform")) - - if np.any(self.trans): - self.phase_r = ListDictKey(alldb, "phase_r") - self.gamma_r = np.array(ListDictKey(alldb, "gamma_r")) - self.amp_r = ListDictKey(alldb, "amp_r") - self.freq_r = np.array(ListDictKey(alldb, "freq_r")) - - # try: - # self.model(haswak=False) # - # except: - # self.M = 0 - - # try: - try: # analytic model based on simple matrix - self.models = [] - # self.models.append(_model(self)) #create a list to contain models - self.models.append( - _model(self, haswak=True, name="haswak") - ) # another model - # self.models.append(_model(self,haswak=True,name='haswak_0',m=0)) - # for Ln in range(10): - # Lval = 10**((.2*Ln -1)/10) - # #Lval = 10**(Ln-1) - # #Lval = - # print Lval - # self.models.append(_model(self,varL=True,name='varL'+str(Lval),Lval=Lval,haswak=True)) - - except: - self.M = 0 - - try: # analytic models based on user defined complex omega - self.ref = [] - self.ref.append(_ref(self)) - # self.ref.append(_ref(self,haswak=False,name='drift')) - # demand a complex omega to compare - # self.ref.append(_ref(self,haswas=True,name='haswak')) - except: - self.ref = 0 - - # self.models.append(_model(self,haswak2=True,name='haswak2')) - - # except: - # print 'FAIL' - - def _amp(self, tind, xind): - # first select modes that actually have valid (tind,xind) - # indecies - # s = subset(self.db,'modeid',modelist) - return np.array([self.amp[i][tind, xind] for i in range(self.nmodes)]) - - # def model(self,field='Ni',plot=False,haswak=False): - - # #enrich the object - # allk = self.k_r[:,1,self.nx/2] #one location for now - # allkpar = self.k_r[:,0,self.nx/2] #one location for now - - # self.M = [] - # self.eigsys = [] - # self.gammaA = [] - # self.omegaA = [] - # self.eigvec = [] - # self.gammamax = [] - # self.omegamax = [] - - # #allk = np.arange(0.1,100.0,.1) - # #allk= np.sort(list(set(allk).union())) - - # for i,k in enumerate(allk): - # #print i - # #M =np.matrix(np.random.rand(3,3),dtype=complex) - # M = np.zeros([3,3],dtype=complex) - # M[0,0] = 0 - # M[0,1] = k/(self.L[i,self.nx/2,self.ny/2]) - # M[1,0] = (2*np.pi/self.meta['lpar'][self.nx/2])**2 * self.meta['sig_par'][0]*complex(0,k**-2) - # M[1,1]= -(2*np.pi/self.meta['lpar'][self.nx/2])**2 * self.meta['sig_par'][0]*complex(0,k**-2) - - # if haswak: - # M[0,0] = M[0,0] + M[1,1]*complex(0,k**2) - # M[0,1] = M[0,1] + M[1,0]*complex(0,k**2) - - # #if rho_conv: - - # #M[1,0] = (allkpar[i])**2 * self.meta['sig_par'][0]*complex(0,k**-2) - # #M[1,1]= -(allkpar[i])**2 * self.meta['sig_par'][0]*complex(0,k**-2) - - # eigsys= np.linalg.eig(M) - # gamma = (eigsys)[0].imag - # omega =(eigsys)[0].real - # eigvec = eigsys[1] - - # self.M.append(M) - # self.eigsys.append(eigsys) - # self.gammaA.append(gamma) - # self.gammamax.append(max(gamma)) - # where = ((gamma == gamma.max()) & (omega != 0)) - # self.omegamax.append(omega[where[0]]) - # self.eigvec.append(eigvec) - # self.omegaA.append(omega) - - class __model__(object): - def __init__(self): - self.M = 0 - - -class subset(LinRes): - def __init__(self, alldb, key, valuelist, model=False): - selection = ListDictFilt(alldb, key, valuelist) - if len(selection) != 0: - LinRes.__init__(self, selection) - self.skey = key - if model == True: - self.model() - else: - LinRes.__init__(self, alldb) - if model == True: - self.model() - - -# class subset(originClass): -# def __init__(self,alldb,key,valuelist,model=False): -# selection = ListDictFilt(alldb,key,valuelist) -# if len(selection) !=0: -# originClass.__init__(self,selection,input_obj.ave_db) -# self.skey = key -# if model==True: -# self.model() -# else: -# origin.__init__(self,alldb) -# if model==True: -# self.model() - -# not sure if this is the best way . . . - - -# class subset(object): -# def __init__(self,input_obj,key,valuelist,model=False): -# selection = ListDictFilt(input_obj.mode_db,key,valuelist) -# if len(selection) !=0: -# import copy -# self = copy.copy(input_obj) -# self.__init__(selection,input_obj.ave_db) -# self.skey = key -# if model==True: -# self.model() -# else: -# self = input_obj -# if model==True: -# self.model() - - -class _ref(object): # NOT a derived obj, just takes one as a var - def __init__(self, input_obj, name="haswak", haswak=True): - allk = input_obj.k_r[:, 1, old_div(input_obj.nx, 2)] # one location for now - allkpar = input_obj.k_r[:, 0, old_div(input_obj.nx, 2)] # one location for now - self.name = name - - self.gamma = [] - self.omega = [] - self.soln = {} - self.soln["gamma"] = [] - self.soln["freq"] = [] - - for i, k in enumerate(allk): - omega_star = old_div( - -(k), - (input_obj.L[i, old_div(input_obj.nx, 2), old_div(input_obj.ny, 2)]), - ) - - nu = ( - 2 * np.pi / input_obj.meta["lpar"][old_div(input_obj.nx, 2)] - ) ** 2 * input_obj.meta["sig_par"][0] - - if haswak: - omega = old_div(-omega_star, (1 + (k) ** 2)) - gamma = old_div(((k**2) * omega_star**2), (nu * (1 + k**2) ** 3)) - else: - # omega = -np.sqrt(nu*omega_star)/(np.sqrt(2)*k) + nu**(3/2)/(8*np.sqrt(2*omega_star)*k**3) - # gamma = np.sqrt(nu*omega_star)/(np.sqrt(2)*k) - nu/(2* k**2) + nu**(3/2)/(8*np.sqrt(2*omega_star)*k**3) - omega = -omega_star + old_div((2 * k**4 * omega_star**3), nu**2) - gamma = old_div((k * omega_star) ** 2, nu) - ( - 5 * (k**6 * omega_star * 4 / nu**3) - ) - self.gamma.append(gamma) - self.omega.append(omega) - - self.soln["freq"] = np.transpose(np.array(self.omega)) - self.soln["gamma"] = np.transpose(np.array(self.gamma)) - - -class _model(object): # NOT a derived class,but one that takes a class as input - def __init__( - self, - input_obj, - name="drift", - haswak=False, - rho_conv=False, - haswak2=False, - varL=False, - Lval=1.0, - m=1, - ): - allk = input_obj.k_r[:, 1, old_div(input_obj.nx, 2)] # one location for now - allkpar = input_obj.k_r[:, 0, old_div(input_obj.nx, 2)] # one location for now - - # numerical value to compare against - - numgam = input_obj.gamma[:, 0, old_div(input_obj.nx, 2)] - numfreq = input_obj.freq[:, 0, old_div(input_obj.nx, 2)] - self.name = name - - self.M = [] - self.eigsys = [] - self.gammaA = [] - self.omegaA = [] - self.eigvec = [] - self.gammamax = [] - self.omegamax = [] - self.k = [] - self.m = m - - self.soln = {} - self.soln["freq"] = [] - self.soln["gamma"] = [] - self.soln["gammamax"] = [] - self.soln["freqmax"] = [] - - self.chi = {} - self.chi["freq"] = [] - self.chi["gamma"] = [] - - for i, k in enumerate(allk): - # print i - # M =np.matrix(np.random.rand(3,3),dtype=complex) - M = np.zeros([4, 4], dtype=complex) - M[0, 0] = 0 - # k = k/np.sqrt(10) - # L = (input_obj.L)*np.sqrt(10) - - if k == 0: - k = 1e-5 - - # print k {n,phi,v,ajpar} - M[0, 1] = old_div( - k, (input_obj.L[i, old_div(input_obj.nx, 2), old_div(input_obj.ny, 2)]) - ) - M[1, 0] = ( - (2 * m * np.pi / input_obj.meta["lpar"][old_div(input_obj.nx, 2)]) ** 2 - * input_obj.meta["sig_par"][0] - * complex(0, (k) ** -2) - ) - M[1, 1] = ( - -( - (2 * m * np.pi / input_obj.meta["lpar"][old_div(input_obj.nx, 2)]) - ** 2 - ) - * input_obj.meta["sig_par"][0] - * complex(0, (k) ** -2) - ) - - # parallel dynamics - # M[2,2] = k/(input_obj.L[i,input_obj.nx/2,input_obj.ny/2]) - # M[2,0] = -(2*m*np.pi/input_obj.meta['lpar'][input_obj.nx/2]) - # M[0,2] = -(2*m*np.pi/input_obj.meta['lpar'][input_obj.nx/2]) - - # M[1,0] = (2*m*np.pi/input_obj.meta['lpar'][input_obj.nx/2])**2 * input_obj.meta['sig_par'][0] - # M[1,1]= -(2*m*np.pi/input_obj.meta['lpar'][input_obj.nx/2])**2 * input_obj.meta['sig_par'][0] - - # ajpar dynamics - effectively parallel electron dynamics instead of - - if haswak: - M[0, 0] = ( - -( - ( - 2 - * m - * np.pi - / input_obj.meta["lpar"][old_div(input_obj.nx, 2)] - ) - ** 2 - ) - * input_obj.meta["sig_par"][0] - * complex(0, 1) - ) - M[0, 1] = ( - 2 * m * np.pi / input_obj.meta["lpar"][old_div(input_obj.nx, 2)] - ) ** 2 * input_obj.meta["sig_par"][0] * complex(0, 1) + M[0, 1] - - if varL: - M[0, 1] = Lval * M[0, 1] - - if rho_conv: # not used - M[1, 0] = ( - (allkpar[i]) ** 2 - * input_obj.meta["sig_par"][0] - * complex(0, (k) ** -2) - ) - M[1, 1] = ( - -((allkpar[i]) ** 2) - * input_obj.meta["sig_par"][0] - * complex(0, (k) ** -2) - ) - - eigsys = np.linalg.eig(M) - gamma = (eigsys)[0].imag - omega = (eigsys)[0].real - eigvec = eigsys[1] - self.k.append(k) - - self.M.append(M) - self.eigsys.append(eigsys) - - self.gammaA.append(gamma) - self.soln["gamma"].append(gamma) - - self.gammamax.append(max(gamma)) - self.soln["gammamax"].append(max(gamma)) - - where = (gamma == gamma.max()) & (omega != 0) - # if len(where) > 1: - # where = where[0] - self.omegamax.append(omega[where]) - self.soln["freqmax"].append(omega[where]) - - # print k,gamma,where,M,omega - chigam = old_div(((numgam - max(gamma)) ** 2), max(gamma)) - chifreq = old_div(((numfreq - omega[where]) ** 2), omega[where]) - - self.eigvec.append(eigvec) - self.omegaA.append(omega) - self.soln["freq"].append(omega) - - self.chi["freq"].append(chifreq[i]) - - self.chi["gamma"].append(chigam[i]) - - self.dim = M.shape[0] - self.soln["freq"] = np.transpose(np.array(self.soln["freq"])) - self.soln["gamma"] = np.transpose(np.array(self.soln["gamma"])) - self.chi["freq"] = np.transpose(np.array(self.chi["freq"])) - self.chi["gamma"] = np.transpose(np.array(self.chi["gamma"])) - - # self.soln = {} - # self.soln['freq'] = self.omegaA - # self.soln['gamma'] = self.gammaA diff --git a/tools/pylib/post_bout/pb_draw.py b/tools/pylib/post_bout/pb_draw.py deleted file mode 100644 index 272aab9c35..0000000000 --- a/tools/pylib/post_bout/pb_draw.py +++ /dev/null @@ -1,1692 +0,0 @@ -from __future__ import print_function -from __future__ import absolute_import -from __future__ import division -from builtins import str -from builtins import range -from past.utils import old_div - -# some standard analytic stuff to plot, if appending just overplot gam or omeg -from .pb_corral import LinRes -from .ListDict import ListDictKey, ListDictFilt -import numpy as np - -import matplotlib.pyplot as plt -from matplotlib import cm -import matplotlib.artist as artist -import matplotlib.ticker as ticker -import matplotlib.pyplot as plt -import matplotlib.patches as patches -from matplotlib.figure import Figure -from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas -from matplotlib.backends.backend_pdf import PdfPages - -from reportlab.platypus import * -from reportlab.lib.styles import getSampleStyleSheet -from reportlab.rl_config import defaultPageSize -from reportlab.lib.units import inch -from reportlab.graphics.charts.linecharts import HorizontalLineChart -from reportlab.graphics.shapes import Drawing -from reportlab.graphics.charts.lineplots import LinePlot -from reportlab.graphics.widgets.markers import makeMarker -from reportlab.lib import colors - -from replab_x_vs_y import RL_Plot -from matplotlib.ticker import ScalarFormatter, FormatStrFormatter, MultipleLocator - - -class LinResDraw(LinRes): - def __init__(self, alldb): - LinRes.__init__(self, alldb) - - def plottheory( - self, pp, m=1, canvas=None, comp="gamma", field="Ni", allroots=False - ): - if len(self.models) == 0: - try: - self.models = [] - self.models.append(_model(self)) # create a list to contain models - self.models.append( - _model(self, haswak=True, name="haswak") - ) # another model - except: - return 0 - - s = subset(self.db, "field", [field]) - - modelist = [] - - [modelist.append([m, n + 1]) for n in range(min(s.maxN) - 1)] - - s = subset(s.db, "mn", modelist) - - allk = s.k[:, 1, old_div(s.nx, 2)] - ki = np.argsort(allk) - - ownpage = False - if canvas is None: - ownpage = True - - if ownpage: # if not an overplot - fig1 = plt.figure() - canvas = fig1.add_subplot(1, 1, 1) - - label = "gamma analytic" - - # if comp=='gamma': - # y = np.array(s.gammamax)[ki] - # else: - # y = np.array(s.omegamax)[ki] - - for m in s.models: - print(m.name) - - for i, m in enumerate(s.models): - print(m.name, comp, m.soln[comp].shape) - - if allroots: - for elem in m.soln[comp]: - # y = [] - # elem has 2 or more elements - y = (np.array(elem)[ki]).flatten() # n values - # y = y.astype('float') - print(y.shape) - canvas.plot( - (allk[ki]).flatten(), y, ",", label=label, c=cm.jet(0.2 * i) - ) - try: - ymax = (np.array(m.soln[comp + "max"])[ki]).flatten() - # ymax = (np.array(m.gammamax)[ki]).flatten() - ymax = ymax.astype("float") - print(comp, " ymax:", ymax) - canvas.plot( - (allk[ki]).flatten(), ymax, "-", label=label, c=cm.jet(0.2 * i) - ) - # if comp=='gamma': - # y = (np.array(m.gammamax)[ki]).flatten() - - # else: - # y = (np.array(m.omegamax)[ki]).flatten() - - # print m.name, ':' ,y.astype('float') - - except: - print("fail to add theory curve") - - canvas.annotate(m.name, (allk[ki[0]], 1.1 * ymax[0]), fontsize=8) - canvas.annotate(m.name, (1.1 * allk[ki[-1]], 1.1 * ymax[-1]), fontsize=8) - - try: - for i, m in enumerate(s.ref): - if not allroots: - y = (np.array(m.soln[comp])[ki]).flatten() - y = y.astype("float") - canvas.plot( - (allk[ki]).flatten(), - y, - "--", - label=label, - c=cm.jet(0.2 * i), - ) - except: - print("no reference curve") - - if ownpage: # set scales if this is its own plot - # canvas.set_yscale('symlog',linthreshy=1e-13) - # canvas.set_xscale('log') - - canvas.axis("tight") - canvas.set_xscale("log") - canvas.set_yscale("symlog") - fig1.savefig(pp, format="pdf") - plt.close(fig1) - else: # if not plot its probably plotted iwth sim data, print chi somewhere - for i, m in enumerate(s.models): - textstr = r"$\chi^2$" + "$=%.2f$" % (m.chi[comp].sum()) - print(textstr) - # textstr = '$\L=%.2f$'%(m.chi[comp].sum()) - props = dict(boxstyle="square", facecolor="white", alpha=0.3) - textbox = canvas.text( - 0.1, - 0.1, - textstr, - transform=canvas.transAxes, - fontsize=10, - verticalalignment="top", - bbox=props, - ) - - def plotomega( - self, - pp, - canvas=None, - field="Ni", - yscale="linear", - clip=0, - xaxis="t", - xscale="linear", - xrange=1, - comp="gamma", - pltlegend="both", - overplot=False, - gridON=True, - trans=False, - infobox=True, - ): - colors = [ - "b.", - "r.", - "k.", - "c.", - "g.", - "y.", - "m.", - "b.", - "r.", - "k.", - "c.", - "g.", - "y.", - "m.", - ] - colordash = [ - "b", - "r", - "k", - "c", - "g", - "y", - "m", - "b", - "r", - "k", - "c", - "g", - "y", - "m", - ] - - if canvas is None: - ownpage = True - else: - ownpage = False - - if ownpage: - fig1 = plt.figure() - fig1.subplots_adjust(bottom=0.12) - fig1.subplots_adjust(top=0.80) - fig1.subplots_adjust(right=0.83) - fig1.subplots_adjust(left=0.17) - canvas = fig1.add_subplot(1, 1, 1) - clonex = canvas.twinx() - # if trans: - # cloney = canvas.twiny() - - dzhandles = [] - parhandles = [] - parlabels = [] - dzlabels = [] - - m_shift = 1 - for q in np.array(list(range(1))) + m_shift: - s = subset(self.db, "field", [field]) # pick field - maxZ = min(s.maxN) - modelist = [] - [modelist.append([q, p + 1]) for p in range(maxZ - 1)] - print(modelist) - print(q, "in plotgamma") - - s = subset(s.db, "mn", modelist) - - xrange = old_div(s.nx, 2) - 2 - - xrange = [old_div(s.nx, 2), old_div(s.nx, 2) + xrange] - - y = np.array(ListDictKey(s.db, comp)) - - # y = s.gamma #nmodes x 2 x nx ndarray - k = s.k ##nmodes x 2 x nx ndarray k_zeta - - kfactor = np.mean( - old_div(s.k_r[:, 1, old_div(s.nx, 2)], s.k[:, 1, old_div(s.nx, 2)]) - ) # good enough for now - - print( - k[:, 1, old_div(s.nx, 2)].shape, - y[:, 0, old_div(s.nx, 2)].shape, - len(colors), - ownpage, - ) # ,k[:,1,s.nx/2],y[:,0,s.nx/2] - - parhandles.append( - canvas.errorbar( - np.squeeze(k[:, 1, old_div(s.nx, 2)]), - np.squeeze(y[:, 0, old_div(s.nx, 2)]), - yerr=np.squeeze(y[:, 1, old_div(s.nx, 2)]), - fmt=colors[q], - ) - ) - - parlabels.append("m " + str(q)) - - # loop over dz sets and connect with dotted line . . . - jj = 0 - - ymin_data = np.max(np.array(ListDictKey(s.db, comp))) - ymax_data = 0 # for bookeeping - - for p in list(set(s.path).union()): - print(p, "in plotomega") - - sub_s = subset(s.db, "path", [p]) - j = sub_s.dz[0] - # print sub_s.amp.shape - s_i = np.argsort(sub_s.mn[:, 1]) # sort by 'local' m, global m is ok also - # print s_i, sub_s.mn, sub_s.nx, jj - y = np.array(ListDictKey(sub_s.db, comp)) - y_alt = 2.0 * np.array(ListDictKey(sub_s.db, comp)) - - k = sub_s.k ## - if q == m_shift: # fix the parallel mode - dzhandles.append( - canvas.plot( - k[s_i, 1, old_div(sub_s.nx, 2)], - y[s_i, 0, old_div(sub_s.nx, 2)], - color=colordash[jj], - alpha=0.5, - ) - ) - # clonex.plot(k[s_i,1,sub_s.nx/2], - # y_alt[s_i,0,sub_s.nx/2],color=colordash[jj],alpha=.5) - # if np.any(sub_s.trans) and trans: - # comp_r = comp+'_r' - # k_r = sub_s.k_r - # y2 = np.array(ListDictKey(sub_s.db,comp_r)) - # cloney.plot(k[s_i,1,sub_s.nx/2], - # y2[s_i,0,sub_s.nx/2],'k.',ms = 3) - - ymin_data = np.min([np.min(y[s_i, 0, old_div(sub_s.nx, 2)]), ymin_data]) - ymax_data = np.max([np.max(y[s_i, 0, old_div(sub_s.nx, 2)]), ymax_data]) - - print("dzhandle color", jj) - # dzlabels.append("DZ: "+ str(2*j)+r'$\pi$') - dzlabels.append(j) - - if yscale == "log": - factor = 10 - else: - factor = 2 - print("annotating") - canvas.annotate( - str(j), - ( - k[s_i[0], 1, old_div(sub_s.nx, 2)], - y[s_i[0], 0, old_div(sub_s.nx, 2)], - ), - fontsize=8, - ) - p = canvas.axvspan( - k[s_i[0], 1, old_div(sub_s.nx, 2)], - k[s_i[-1], 1, old_div(sub_s.nx, 2)], - facecolor=colordash[jj], - alpha=0.01, - ) - print("done annotating") - else: - canvas.plot( - k[s_i, 1, old_div(sub_s.nx, 2)], - y[s_i, 0, old_div(sub_s.nx, 2)], - color=colordash[jj], - alpha=0.3, - ) - - jj = jj + 1 - - dzhandles = np.array(dzhandles).flatten() - dzlabels = np.array(dzlabels).flatten() - - dzlabels = list(set(dzlabels).union()) - - dz_i = np.argsort(dzlabels) - - dzhandles = dzhandles[dz_i] - dzlabels_cp = np.array(dzlabels)[dz_i] - - print(type(dzlabels), np.size(dzlabels)) - for i in range(np.size(dzlabels)): - dzlabels[i] = "DZ: " + str(dzlabels_cp[i]) # +r"$\pi$" - - parlabels = np.array(parlabels).flatten() - - # if pltlegend =='both': # - - print("legends") - - # l1 = legend(parhandles,parlabels,loc = 3,prop={'size':6}) - # l2 = legend(dzhandles,dzlabels,loc = 1,prop={'size':6}) - # plt.gca().add_artist(l1) - - # else: - # legend(dzhandles,dzlabels,loc=3,prop={'size':6}) - if overplot == True: - try: - self.plottheory(pp, canvas=canvas, comp=comp, field=field) - # self.plottheory(pp,comp=comp) - except: - print("no theory plot") - if infobox: - textstr = "$\L_{\parallel}=%.2f$\n$\L_{\partial_r n}=%.2f$\n$B=%.2f$" % ( - s.meta["lpar"][old_div(s.nx, 2)], - s.meta["L"][old_div(s.nx, 2), old_div(s.ny, 2)], - s.meta["Bpxy"]["v"][old_div(s.nx, 2), old_div(s.ny, 2)], - ) - props = dict(boxstyle="square", facecolor="white", alpha=0.3) - textbox = canvas.text( - 0.82, - 0.95, - textstr, - transform=canvas.transAxes, - fontsize=10, - verticalalignment="top", - bbox=props, - ) - # leg = canvas.legend(handles,labels,ncol=2,loc='best',prop={'size':4},fancybox=True) - # textbox.get_frame().set_alpha(0.3) - # matplotlib.patches.Rectangle - # p = patches.Rectangle((0, 0), 1, 1, fc="r") - # p = str('L_par') - # leg = canvas.legend([p], ["Red Rectangle"],loc='best',prop={'size':4}) - # leg.get_frame().set_alpha(0.3) - - # cloney.set_xlim(xmin,xmax) - try: - canvas.set_yscale(yscale) - canvas.set_xscale(xscale) - - if yscale == "symlog": - canvas.set_yscale(yscale, linthreshy=1e-13) - if xscale == "symlog": - canvas.set_xscale(xscale, linthreshy=1e-13) - - if gridON: - canvas.grid() - except: - try: - canvas.set_yscale("symlog") - except: - print("scaling failed completely") - - # print '[xmin, xmax, ymin, ymax]: ',[xmin, xmax, ymin, ymax] - - clonex.set_yscale(yscale) # must be called before limits are set - - try: - if yscale == "linear": - formatter = ticker.ScalarFormatter() - formatter.set_powerlimits((-2, 2)) # force scientific notation - canvas.yaxis.set_major_formatter(formatter) - clonex.yaxis.set_major_formatter(formatter) - # canvas.useOffset=False - except: - print("fail 1") - [xmin, xmax, ymin, ymax] = canvas.axis() - - if yscale == "symlog": - clonex.set_yscale(yscale, linthreshy=1e-9) - if xscale == "symlog": - clonex.set_xscale(xscale, linthreshy=1e-9) - # if np.any(s.trans) and trans: - [xmin1, xmax1, ymin1, ymax1] = canvas.axis() - if trans: - try: - cloney = canvas.twiny() - # cloney.set_yscale(yscale) - cloney.set_xscale(xscale) - [xmin1, xmax1, ymin2, ymax2] = canvas.axis() - - if xscale == "symlog": - cloney.set_xscale(xscale, linthreshy=1e-9) - if yscale == "symlog": - cloney.set_yscale(yscale, linthreshy=1e-9) - if yscale == "linear": - cloney.yaxis.set_major_formatter(formatter) - except: - print("fail trans") - # cloney.useOffset=False - - # if xscale =='symlog' and trans: - # cloney.set_yscale(yscale,linthreshy=1e-9) - # cloney.set_xscale(xscale,linthreshy=1e-9) - - Ln_drive_scale = s.meta["w_Ln"][0] ** -1 - # Ln_drive_scale = 2.1e3 - clonex.set_ylim(Ln_drive_scale * ymin, Ln_drive_scale * ymax) - - try: - if trans: - # k_factor = #scales from k_zeta to k_perp - cloney.set_xlim(kfactor * xmin, kfactor * xmax) - # if np.any(sub_s.trans) and trans: - # comp_r = comp+'_r' - # y2 = np.array(ListDictKey(sub_s.db,comp_r)) - # #canvas.plot(k[s_i,1,sub_s.nx/2], - # # y2[s_i,0,sub_s.nx/2],'k.',ms = 3) - - # cloney.plot(k_r[s_i,1,sub_s.nx/2], - # y2[s_i,0,sub_s.nx/2],'k.',ms = 3) - # print 'np.sum(np.abs(y-y2)): ',np.sum(np.abs(y-y2)),comp_r - # kfactor =1.0 - # cloney.set_xlim(xmin,xmax) - cloney.set_ylim( - ymin, ymax - ) # because cloney shares the yaxis with canvas it may overide them, this fixes that - cloney.set_xlabel(r"$k_{\perp} \rho_{ci}$", fontsize=18) - except: - print("moar fail") - # clonex.set_xscale(xscale) - - # except: - # #canvas.set_xscale('symlog', linthreshx=0.1) - # print 'extra axis FAIL' - - # if yscale == 'linear': - # canvas.yaxis.set_major_locator(ticker.LinearLocator(numticks=8)) - - # minorLocator = MultipleLocator(.005) - # canvas.yaxis.set_minor_locator(minorLocator) - # spawn another y label - - # clone = canvas.twinx() - # s2 = np.sin(2*np.pi*t) - # ax2.plot(x, s2, 'r.') - - # ion_acoust_str = r"$\frac{c_s}{L_{\partial_r n}}}$" - - if comp == "gamma": - canvas.set_ylabel( - r"$\frac{\gamma}{\omega_{ci}}$", fontsize=18, rotation="horizontal" - ) - clonex.set_ylabel( - r"$\frac{\gamma}{\frac{c_s}{L_n}}$", - color="k", - fontsize=18, - rotation="horizontal", - ) - if comp == "freq": - canvas.set_ylabel( - r"$\frac{\omega}{\omega_{ci}}$", fontsize=18, rotation="horizontal" - ) - clonex.set_ylabel( - r"$\frac{\omega}{\frac{c_s}{L_n}}$", - color="k", - fontsize=18, - rotation="horizontal", - ) - - if comp == "amp": - canvas.set_ylabel(r"$A_k$", fontsize=18, rotation="horizontal") - clonex.set_ylabel( - r"$\frac{A_k}{A_{max}}$", color="k", fontsize=18, rotation="horizontal" - ) - - canvas.set_xlabel(r"$k_{\zeta} \rho_{ci}$", fontsize=18) - - title = comp + " computed from " + field - # canvas.set_title(title,fontsize=14) - fig1.suptitle(title, fontsize=14) - - if ownpage: - try: - fig1.savefig(pp, format="pdf") - except: - print("pyplt doesnt like you") - plt.close(fig1) - - def plotfreq( - self, pp, field="Ni", clip=0, xaxis="t", xscale="linear", yscale="linear" - ): - # colors = ['b','g','r','c','m','y','k','b','g','r','c','m','y','k'] - colors = [ - "b.", - "g.", - "r.", - "c.", - "m.", - "y.", - "k.", - "b.", - "g.", - "r.", - "c.", - "m.", - "y", - "k", - ] - plt.figure() - - # s = subset(self.db,'field',[field]) #pick field - - for q in range(4): - s = subset(self.db, "field", [field]) # pick field across all dz sets - modelist = [] - [modelist.append([q + 1, p + 1]) for p in range(5)] - print(q, "in plotgamma") - s = subset(s.db, "mn", modelist) - - gamma = s.freq # nmodes x 2 x nx ndarray - k = s.k ##nmodes x 2 x nx ndarray - - plt.errorbar( - k[:, 1, old_div(s.nx, 2)], - gamma[:, 0, old_div(s.nx, 2)], - yerr=gamma[:, 1, old_div(s.nx, 2)], - fmt=colors[q], - ) - plt.plot( - k[:, 1, old_div(s.nx, 2)], - gamma[:, 0, old_div(s.nx, 2)], - "k:", - alpha=0.3, - ) - - # loop over dz sets and connect with dotted line . . . - for j in list(set(s.dz).union()): - # print j,len(s.mn) - sub_s = subset(s.db, "dz", [j]) - gamma = sub_s.gamma - k = sub_s.k ## - plt.plot( - k[:, 1, old_div(sub_s.nx, 2)], - gamma[:, 0, old_div(sub_s.nx, 2)], - "k:", - alpha=0.1, - ) - - try: - plt.yscale(yscale) - except: - print("yscale fail") - - try: - plt.xscale(yscale) - except: - plt.xscale("symlog") - plt.xlabel(r"$k \rho_{ci}$", fontsize=14) - plt.ylabel(r"$\frac{\omega}{\omega_{ci}}$", fontsize=14) - # plt.title(r'$\frac{\omega}\{\omega_{ci}}$ '+ 'computed from'+field+ 'field',fontsize=10) - - plt.savefig(pp, format="pdf") - plt.close() - - def plotgamma( - self, - pp, - field="Ni", - yscale="symlog", - clip=0, - xaxis="t", - xscale="linear", - xrange=1, - comp="gamma", - overplot=False, - trans=True, - ): - self.plotomega( - pp, - field=field, - yscale=yscale, - clip=clip, - xaxis=xaxis, - xscale=xscale, - xrange=xrange, - comp=comp, - overplot=overplot, - trans=trans, - ) - - def plotfreq2( - self, - pp, - field="Ni", - yscale="symlog", - clip=0, - xaxis="t", - xscale="linear", - xrange=1, - comp="freq", - overplot=False, - trans=True, - ): - self.plotomega( - pp, - field=field, - yscale=yscale, - clip=clip, - xaxis=xaxis, - xscale=xscale, - xrange=xrange, - comp=comp, - overplot=overplot, - trans=trans, - ) - - def plotvsK( - self, - pp, - rootfig=None, - field="Ni", - yscale="log", - clip=0, - xaxis="t", - xscale="linear", - xrange=1, - comp="amp", - pltlegend="both", - overplot=False, - gridON=True, - trans=False, - infobox=True, - m=1, - t=[0], - file=None, - save=True, - ): - colors = [ - "b.", - "r.", - "k.", - "c.", - "g.", - "y.", - "m.", - "b.", - "r.", - "k.", - "c.", - "g.", - "y.", - "m.", - ] - colordash = [ - "b", - "r", - "k", - "c", - "g", - "y", - "m", - "b", - "r", - "k", - "c", - "g", - "y", - "m", - ] - - if rootfig is None: - ownpage = True - else: - ownpage = False - - if ownpage: - fig1 = plt.figure() - fig1.subplots_adjust(bottom=0.12) - fig1.subplots_adjust(top=0.80) - fig1.subplots_adjust(right=0.83) - fig1.subplots_adjust(left=0.17) - canvas = fig1.add_subplot(1, 1, 1) - clonex = canvas.twinx() - # if trans: - # cloney = canvas.twiny() - else: - canvas = rootfig.add_subplot(1, 1, 1) - - dzhandles = [] - parhandles = [] - parlabels = [] - dzlabels = [] - - # pick the modes - m_shift = m - for q in np.array(list(range(1))) + m_shift: - s = subset(self.db, "field", [field]) # pick field - maxZ = min(s.maxN) - modelist = [] - [modelist.append([q, p + 1]) for p in range(maxZ - 1)] - # print q,'in plotgamma' - s = subset(s.db, "mn", modelist) - - # set x-range - xrange = old_div(s.nx, 2) - 2 - xrange = [old_div(s.nx, 2), old_div(s.nx, 2) + xrange] - - # pull up the data - y = np.array(ListDictKey(s.db, comp)) - print("y.shape", y.shape) - - # in case multiple timesteps are indicated - all_y = [] - all_yerr = [] - if comp == "amp": - for elem in t: - all_y.append(np.squeeze(y[:, elem, :])) - all_yerr.append(np.squeeze(0 * y[:, elem, :])) - ynorm = np.max(all_y) - # all_y = np.array(np.squeeze(all_y)) - # all_yerr = np.array(np.squeeze(all_yerr)) - - else: - all_y.append(np.squeeze(y[:, 0, :])) - all_yerr.append(np.squeeze(y[:, 1, :])) - ynorm = s.meta["w_Ln"][0] - - k = s.k ##nmodes x 2 x nx ndarray k_zeta - - kfactor = np.mean( - old_div(s.k_r[:, 1, old_div(s.nx, 2)], s.k[:, 1, old_div(s.nx, 2)]) - ) # good enough for now - - for elem in range(np.size(t)): - # print 'printing line' , elem - errorline = parhandles.append( - canvas.errorbar( - k[:, 1, old_div(s.nx, 2)], - all_y[elem][:, old_div(s.nx, 2)], - yerr=all_yerr[elem][:, old_div(s.nx, 2)], - fmt=colors[q], - ) - ) - - parlabels.append("m " + str(q)) - - # loop over dz sets and connect with dotted line . . . - jj = 0 # will reference dz color - - ymin_data = np.max(np.array(ListDictKey(s.db, comp))) - ymax_data = 0 # for bookeeping - - for p in list(set(s.path).union()): - sub_s = subset(s.db, "path", [p]) - j = sub_s.dz[0] - # print sub_s.amp.shape - s_i = np.argsort(sub_s.mn[:, 1]) # sort by 'local' m, global m is ok also - # print s_i, sub_s.mn, sub_s.nx, jj - y = np.array(ListDictKey(sub_s.db, comp)) - y_alt = 2.0 * np.array(ListDictKey(sub_s.db, comp)) - all_y = [] - all_yerr = [] - if comp == "amp": - for elem in t: - all_y.append(np.squeeze(y[:, elem, :])) - all_yerr.append(np.squeeze(0 * y[:, elem, :])) - else: - all_y.append(np.squeeze(y[:, 0, :])) - all_yerr.append(np.squeeze(y[:, 1, :])) - - k = sub_s.k ## - - for elem in range(np.size(t)): - if q == m_shift: # fix the parallel mode - dzhandles.append( - canvas.plot( - k[s_i, 1, old_div(sub_s.nx, 2)], - all_y[elem][s_i, old_div(sub_s.nx, 2)], - color=colordash[jj], - alpha=0.5, - ) - ) - - ymin_data = np.min( - [np.min(y[s_i, old_div(sub_s.nx, 2)]), ymin_data] - ) - ymax_data = np.max( - [np.max(y[s_i, old_div(sub_s.nx, 2)]), ymax_data] - ) - - dzlabels.append(j) - - if yscale == "log": - factor = 10 - else: - factor = 2 - # print 'annotating' - canvas.annotate( - str(j), - ( - k[s_i[0], 1, old_div(sub_s.nx, 2)], - y[elem][s_i[0], old_div(sub_s.nx, 2)], - ), - fontsize=8, - ) - # p = canvas.axvspan(k[s_i[0],1,sub_s.nx/2], k[s_i[-1],1,sub_s.nx/2], - # facecolor=colordash[jj], alpha=0.01) - print("done annotating") - else: - canvas.plot( - k[s_i, 1, old_div(sub_s.nx, 2)], - y[elem][s_i, old_div(sub_s.nx, 2)], - color=colordash[jj], - alpha=0.3, - ) - - jj = jj + 1 - - dzhandles = np.array(dzhandles).flatten() - dzlabels = np.array(dzlabels).flatten() - - dzlabels = list(set(dzlabels).union()) - - dz_i = np.argsort(dzlabels) - - dzhandles = dzhandles[dz_i] - dzlabels_cp = np.array(dzlabels)[dz_i] - - # print type(dzlabels), np.size(dzlabels) - for i in range(np.size(dzlabels)): - dzlabels[i] = "DZ: " + str(dzlabels_cp[i]) # +r"$\pi$" - - parlabels = np.array(parlabels).flatten() - - if overplot == True: - try: - self.plottheory(pp, canvas=canvas, comp=comp, field=field) - # self.plottheory(pp,comp=comp) - except: - print("no theory plot") - if infobox: - textstr = "$\L_{\parallel}=%.2f$\n$\L_{\partial_r n}=%.2f$\n$B=%.2f$" % ( - s.meta["lpar"][old_div(s.nx, 2)], - s.meta["L"][old_div(s.nx, 2), old_div(s.ny, 2)], - s.meta["Bpxy"]["v"][old_div(s.nx, 2), old_div(s.ny, 2)], - ) - props = dict(boxstyle="square", facecolor="white", alpha=0.3) - textbox = canvas.text( - 0.82, - 0.95, - textstr, - transform=canvas.transAxes, - fontsize=10, - verticalalignment="top", - bbox=props, - ) - # leg = canvas.legend(handles,labels,ncol=2,loc='best',prop={'size':4},fancybox=True) - - # cloney.set_xlim(xmin,xmax) - try: - canvas.set_yscale(yscale) - canvas.set_xscale(xscale) - - if yscale == "symlog": - canvas.set_yscale(yscale, linthreshy=1e-13) - if xscale == "symlog": - canvas.set_xscale(xscale, linthreshy=1e-13) - - if gridON: - canvas.grid() - except: - try: - canvas.set_yscale("symlog") - except: - print("scaling failed completely") - - ################################################################## - - if ownpage and rootfig is None: - clonex.set_yscale(yscale) # must be called before limits are set - - try: - if yscale == "linear": - formatter = ticker.ScalarFormatter() - formatter.set_powerlimits((-2, 2)) # force scientific notation - canvas.yaxis.set_major_formatter(formatter) - clonex.yaxis.set_major_formatter(formatter) - # canvas.useOffset=False - except: - print("fail 1") - [xmin, xmax, ymin, ymax] = canvas.axis() - - if yscale == "symlog": - clonex.set_yscale(yscale, linthreshy=1e-9) - if xscale == "symlog": - clonex.set_xscale(xscale, linthreshy=1e-9) - # if np.any(s.trans) and trans: - [xmin1, xmax1, ymin1, ymax1] = canvas.axis() - if trans: - try: - cloney = canvas.twiny() - # cloney.set_yscale(yscale) - cloney.set_xscale(xscale) - [xmin1, xmax1, ymin2, ymax2] = canvas.axis() - - if xscale == "symlog": - cloney.set_xscale(xscale, linthreshy=1e-9) - if yscale == "symlog": - cloney.set_yscale(yscale, linthreshy=1e-9) - if yscale == "linear": - cloney.yaxis.set_major_formatter(formatter) - except: - print("fail trans") - - Ln_drive_scale = s.meta["w_Ln"][0] ** -1 - # Ln_drive_scale = 2.1e3 - # clonex.set_ylim(Ln_drive_scale*ymin, Ln_drive_scale*ymax) - clonex.set_ylim(ynorm**-1 * ymin, ynorm**-1 * ymax) - - try: - if trans: - # k_factor = #scales from k_zeta to k_perp - cloney.set_xlim(kfactor * xmin, kfactor * xmax) - - cloney.set_ylim( - ymin, ymax - ) # because cloney shares the yaxis with canvas it may overide them, this fixes that - cloney.set_xlabel(r"$k_{\perp} \rho_{ci}$", fontsize=18) - except: - print("moar fail") - # clonex.set_xscale(xscale) - - # ion_acoust_str = r"$\frac{c_s}{L_{\partial_r n}}}$" - - if comp == "gamma": - canvas.set_ylabel( - r"$\frac{\gamma}{\omega_{ci}}$", fontsize=18, rotation="horizontal" - ) - clonex.set_ylabel( - r"$\frac{\gamma}{\frac{c_s}{L_n}}$", - color="k", - fontsize=18, - rotation="horizontal", - ) - if comp == "freq": - canvas.set_ylabel( - r"$\frac{\omega}{\omega_{ci}}$", fontsize=18, rotation="horizontal" - ) - clonex.set_ylabel( - r"$\frac{\omega}{\frac{c_s}{L_n}}$", - color="k", - fontsize=18, - rotation="horizontal", - ) - - if comp == "amp": - canvas.set_ylabel(r"$A_k$", fontsize=18, rotation="horizontal") - clonex.set_ylabel( - r"$\frac{A_k}{A_{max}}$", - color="k", - fontsize=18, - rotation="horizontal", - ) - - canvas.set_xlabel(r"$k_{\zeta} \rho_{ci}$", fontsize=18) - - title = comp + " computed from " + field - # canvas.set_title(title,fontsize=14) - fig1.suptitle(title, fontsize=14) - - if not ownpage: - print("probably for a movie") - fig1 = rootfig - # canvasjunk = fig1.add_subplot(1,1,1) - # canvasjunk = canvas - - if save: - if file is None: - try: - fig1.savefig(pp, format="pdf") - except: - print("pyplt doesnt like you") - else: - try: - fig1.savefig(file, dpi=200) - except: - print("no movie for you ;(") - - if ownpage: - # fig1.close() - plt.close(fig1) - - def plotmodes( - self, - pp, - field="Ni", - comp="amp", - math="1", - ylim=1, - yscale="symlog", - clip=False, - xaxis="t", - xscale="linear", - xrange=1, - debug=False, - yaxis=r"$\frac{Ni}{Ni_0}$", - linestyle="-", - summary=True, - ): - Nplots = self.nrun - - colors = ["b", "g", "r", "c", "m", "y", "k", "b", "g", "r", "c", "m", "y", "k"] - styles = ["^", "s"] - - fig1 = plt.figure() - - fig2 = plt.figure() - - Modes = subset(self.db, "field", [field]) # pick field - - adj = fig2.subplots_adjust(hspace=0.4, wspace=0.4) - fig2.suptitle("Dominant mode " + comp + " for " + field) - props = dict(alpha=0.8, edgecolors="none") - - allcurves = fig1.add_subplot(1, 1, 1) - fig1.suptitle("Dominant mode behavior for " + field) - - modenames = [] - k = 0 - - for j in list(set(Modes.path).union()): # - s = subset(Modes.db, "path", [j]) # pick run - dz = s.dz[0] - xr = list( - range( - old_div(s.nx, 2) - old_div(xrange, 2), - old_div(s.nx, 2) + old_div(xrange, 2) + 1, - ) - ) - data = np.array( - ListDictKey(s.db, comp) - ) # pick component should be ok for a fixed dz key - - data = data # + 1e-32 #hacky way to deal with buggy scaling - ax = fig2.add_subplot(round(old_div(Nplots, 3.0) + 1.0), 3, k + 1) - - ax.grid(True, linestyle="-", color=".75") - handles = [] - # modenames.append(str(j)) - - # find the "biggest" mode for this dz - d = data[:, s.nt[0] - 1, :] # nmode X nx array - # d = s.gamma[:,2,:] - where = d == np.nanmax(d) - z = where.nonzero() # mode index and n index - imax = z[0][0] - # xi_max = z[1][0] - xi_max = old_div(s.nx, 2) - - if debug and yscale == "log": - gamma = np.array(ListDictKey(s.db, "gamma")) # nmodes x 2 x nx - - for i in range(s.nmodes): - if math == "gamma": - out = old_div(np.gradient(data[i, :, xr])[1], data[i, :, xr]) - else: - out = data[i, 2:, xi_max] # skip the first 2 points - - if xaxis == "t": - # print 'out.size', out.size, out.shape - x = np.array(list(range(out.size))) - # plt.plot(x,out.flatten(),c=colors[k]) - label = str(s.mn[i]) - # handles.append(ax.plot(x,out.flatten(), - # c=cm.jet(1.*k),label = label)) - ax.plot( - x, out.flatten(), c=cm.jet(0.2 * i), label=label, linestyle="-" - ) - - else: - x = np.array(ListDictKey(s.db, xaxis))[i, :, xr] - # x #an N? by nx array - print(x[:, 1], out[:, 0]) - plt.scatter(x[:, 1], out[:, 0]) # ,c=colors[k]) - ax.scatter( - x[:, 1], out[:, 0] - ) # ,c=colors[k])#,alpha = (1 +i)/s.nmodes) - - # detect error (bar data - print("error bars:", x, out) - - # ax.legend(handles,labels,loc='best',prop={'size':6}) - - formatter = ticker.ScalarFormatter() - formatter.set_powerlimits((0, 0)) - ax.xaxis.set_major_formatter(formatter) - # ax.axis('tight') - if yscale == "linear": - ax.yaxis.set_major_formatter(formatter) - if yscale == "symlog": - ax.set_yscale("symlog", linthreshy=1e-13) - else: - try: - ax.set_yscale(yscale) - except: - print("may get weird axis") - ax.set_yscale("symlog") - # if comp=='phase' or yscale=='linear': - # ax.set_xscale('symlog',linthreshx=1.0) - - ax.set_xscale(xscale) - - ax.axis("tight") - artist.setp(ax.axes.get_xticklabels(), fontsize=6) - artist.setp(ax.axes.get_yticklabels(), fontsize=8) - # artist.setp(ax.axes.get_yscale(), fontsize=8) - ax.set_title(str(dz), fontsize=10) - ax.set_xlabel(xaxis) - handles, labels = ax.get_legend_handles_labels() - leg = ax.legend( - handles, labels, ncol=2, loc="best", prop={"size": 4}, fancybox=True - ) - leg.get_frame().set_alpha(0.3) - # x = s.Rxy[imax,:,s.ny/2] - - t0 = 2 - if clip == True: - t0 = round(old_div(s.nt[0], 3)) - y = np.squeeze(data[imax, t0:, xi_max]) - x = np.array(list(range(y.size))) - - print(imax, xi_max) - - label = ( - str([round(elem, 3) for elem in s.MN[imax]]) - + str(s.mn[imax]) - + " at x= " - + str(xi_max) - + " ," - + str( - round( - old_div(s.gamma[imax, 2, xi_max], s.gamma[imax, 0, xi_max]), 3 - ) - ) - + "% " - + str(round(s.gamma[imax, 0, xi_max], 4)) - ) - - short_label = str(dz) - print(short_label, x.shape, y.shape) - allcurves.plot(x, y, ".", c=cm.jet(1.0 * k / len(x)), label=label) - # print len(x), k*len(x)/(Nplots+2),s.nrun - allcurves.annotate( - short_label, - (x[k * len(x) / (Nplots + 1)], y[k * len(x) / (Nplots + 1)]), - fontsize=8, - ) - - # modenames.append(str([round(elem,3) for elem in s.MN[imax]]) - # +str(s.mn[imax])+' at x= '+str(xi_max)+' ,'+str(s.gamma[imax,2,xi_max])) - - if debug and yscale == "log": - gam = gamma[imax, 0, xi_max] - f0 = gamma[imax, 1, xi_max] - allcurves.plot(x, f0 * np.exp(gam * s.dt[imax] * x), "k:") - - k += 1 - - # if ylim: - # allcurves.set_ylim(data[,xi_max].min(),5*data[:,xi_max].max()) - - fig2.savefig(pp, format="pdf") - - handles, labels = allcurves.get_legend_handles_labels() - allcurves.legend(handles, labels, loc="best", prop={"size": 6}) - # allcurves.legend(modenames,loc='best',prop={'size':6}) - allcurves.set_title( - field + " " + comp + ", all runs, " + yscale + " yscale", fontsize=10 - ) - allcurves.set_ylabel(yaxis) - allcurves.set_xlabel(xaxis) - - if yscale == "linear": - allcurves.yaxis.set_major_formatter(formatter) - else: - try: - allcurves.set_yscale(yscale) - except: - print("may get weird axis scaling") - if yscale == "log": - allcurves.axis("tight") - # allcurves.set_ylim(data.min(),data.max()) - # allcurves.set_yscale(yscale,nonposy='mask') - - # plt.xscale(xscale) - - # plt.legend(modenames,loc='best') - if summary: - fig1.savefig(pp, format="pdf") - plt.close(fig1) - - plt.close(fig2) - - # except: - # print "Sorry you fail" - - def plotradeigen( - self, pp, field="Ni", comp="amp", yscale="linear", xscale="linear" - ): - Nplots = self.nrun - colors = ["b", "g", "r", "c", "m", "y", "k", "b", "g", "r", "c", "m", "y", "k"] - fig1 = plt.figure() - - fig2 = plt.figure() - adj = fig2.subplots_adjust(hspace=0.4, wspace=0.4) - - # canvas = FigureCanvas(fig) - - Modes = subset(self.db, "field", [field]) - - k = 0 - fig2.suptitle("Dominant mode behavior for " + field) - props = dict(alpha=0.8, edgecolors="none") - - allcurves = fig1.add_subplot(1, 1, 1) - fig1.suptitle("Dominant mode behavior for " + field) - - modeleg = [] - - for p in list(set(Modes.path).union()): - print(p) - s = subset(Modes.db, "path", [p]) # pick run - # data = np.array(ListDictKey(s.db,comp)) #pick component - j = s.dz[0] - ax = fig2.add_subplot(round(old_div(Nplots, 3.0) + 1.0), 3, k + 1) - ax.grid(True, linestyle="-", color=".75") - data = np.array(ListDictKey(s.db, comp)) # pick component - handles = [] - - # find the "biggest" mode for this dz - d = data[:, s.nt[0] - 1, :] # nmode X nx array - where = d == d.max() - z = where.nonzero() # mode index and n index - imax = z[0][0] - modeleg.append( - str([round(elem, 3) for elem in s.MN[imax]]) + str(s.mn[imax]) - ) - - # str(s.k[:,1,:][z]) - - for i in range(s.nmodes): - # out = mode[mode.ny/2,:] - # print i,s.Rxynorm.shape,s.ny - x = np.squeeze(s.Rxynorm[i, :, old_div(s.ny, 2)]) - y = data[i, s.nt[0] - 1, :] - - handles.append(ax.plot(x, y, c=cm.jet(1.0 * k / len(x)))) - - formatter = ticker.ScalarFormatter() - formatter.set_powerlimits((0, 0)) - ax.xaxis.set_major_formatter(formatter) - - if yscale == "linear": - ax.yaxis.set_major_formatter(formatter) - else: - ax.set_yscale(yscale) - - artist.setp(ax.axes.get_xticklabels(), fontsize=6) - artist.setp(ax.axes.get_yticklabels(), fontsize=8) - # artist.setp(ax.axes.get_yscale(), fontsize=8) - ax.set_title(str(j), fontsize=10) - - x = np.squeeze(s.Rxynorm[imax, :, old_div(s.ny, 2)]) - y = data[imax, s.nt[0] - 1, :] - # allcurves.plot(x,y,c= colors[k]) - allcurves.plot(x, y, c=cm.jet(0.1 * k / len(x))) - print(k) - k = k + 1 - - fig2.savefig(pp, format="pdf") - if yscale == "linear": - allcurves.yaxis.set_major_formatter(formatter) - else: - allcurves.set_yscale(yscale) - try: - allcurves.set_xscale(xscale) - except: - allcurves.set_xscale("symlog") - - # allcurves.xaxis.set_major_formatter(ticker.NullFormatter()) - allcurves.legend(modeleg, loc="best", prop={"size": 6}) - allcurves.set_xlabel(r"$\frac{x}{\rho_{ci}}$") - allcurves.set_ylabel(r"$\frac{Ni}{Ni_0}$") - fig1.savefig(pp, format="pdf") - plt.close(fig1) - plt.close(fig2) - - def plotmodes2( - self, - pp, - field="Ni", - comp="amp", - math="1", - ylim=1, - yscale="symlog", - clip=0, - xaxis="t", - xscale="linear", - xrange=1, - debug=False, - ): - Nplots = self.nrun - Modes = subset(self.db, "field", [field]) # pick field - colors = ["b", "g", "r", "c", "m", "y", "k", "b", "g", "r", "c", "m", "y", "k"] - - fig = Figure() - plt.figure() - - canvas = FigureCanvas(fig) - k = 0 - nrow = round(old_div(Nplots, 3.0) + 1.0) - ncol = 3 - # nrow = round(Nplots/3.0 + 1.0) - # ncol = round(Nplots/3.0 + 1.0) - f, axarr = plt.subplots(int(nrow), int(ncol)) - - for p in list(set(Modes.path).union()): # - s = subset(Modes.db, "path", [p]) # pick run - j = s.dz[0] - xr = list( - range( - old_div(s.nx, 2) - old_div(xrange, 2), - old_div(s.nx, 2) + old_div(xrange, 2) + 1, - ) - ) - data = np.array(ListDictKey(s.db, comp)) # pick component - # ax =fig.add_subplot(round(Nplots/3.0 + 1.0),3,k+1) - - for i in range(s.nmodes): - out = data[i, :, xr] - - print(j, i) - if xaxis == "t": - x = list(range(out.size)) - # plt.scatter(x,out.flatten(),c=colors[k]) - plt.scatter(x, out.flatten(), c=cm.jet(1.0 * k / len(x))) - # axarr[j%(ncol),j/ncol].scatter(x,out.flatten(),c=colors[k])#,alpha = (1 +i)/s.nmodes) - axarr[old_div(j, ncol), j % (ncol)].scatter( - x, out.flatten(), c=cm.jet(1.0 * k / len(x)) - ) # - - else: - x = np.array(ListDictKey(s.db, xaxis))[i, :, xr] - # x #an N? by nx array - print(x[:, 1], out[:, 0]) - plt.scatter(x[:, 1], out[:, 0]) # ,c=colors[k]) - axarr[j % (col), old_div(j, col)].scatter( - x[:, 1], out[:, 0] - ) # ,c=colors[k])#,alpha = (1 +i)/s.nmodes) - - # detect error (bar data - print("error bars:", x, out) - - axarr[old_div(j, ncol), j % (ncol)].set_yscale(yscale) - axarr[old_div(j, ncol), j % (ncol)].set_xscale(xscale) - axarr[old_div(j, ncol), j % (ncol)].set_title(str(j), fontsize=10) - axarr[old_div(j, ncol), j % (ncol)].set_xlabel(xaxis) - - plt.setp([a.get_xticklabels() for a in axarr[0, :]], visible=False) - plt.setp([a.get_yticklabels() for a in axarr[:, ncol - 1]], visible=False) - - if ylim: - axarr[j % (ncol), old_div(j, ncol)].set_ylim(data.min(), 5 * data.max()) - k += 1 - - plt.title(field + " " + comp + ", all runs, " + yscale + " yscale", fontsize=10) - plt.xlabel(xaxis) - if ylim: - plt.ylim(data.min(), 10 * data.max()) - - plt.yscale(yscale, nonposy="mask") - plt.xscale(xscale) - - fig.savefig(pp, format="pdf") - plt.savefig(pp, format="pdf") - - plt.close() - - return 0 - - def plotMacroDep( - self, - pp, - field="Ni", - yscale="symlog", - clip=0, - xaxis="t", - xscale="linear", - xrange=1, - ): - colors = ["b", "g", "r", "c", "m", "y", "k", "b", "g", "r", "c", "m", "y", "k"] - plt.figure() - - def savemovie( - self, field="Ni", yscale="log", xscale="log", moviename="spectrum.avi" - ): - print("Making movie animation.mpg - this make take a while") - files = [] - - for t in range(self.nt[0] - 3): - print(t) - filename = str("%03d" % (t + 1) + ".png") - self.plotvsK( - "dont need pp", - yscale="log", - t=[1, t + 2], - xscale="log", - overplot=False, - comp="amp", - trans=True, - file=filename, - ) - files.append(filename) - - command = ( - "mencoder", - "mf://*.png", - "-mf", - "type=png:w=800:h=600:fps=10", - "-ovc", - "lavc", - "-lavcopts", - "vcodec=mpeg4", - "-oac", - "copy", - "-o", - moviename, - ) - - import subprocess, os - - subprocess.check_call(command) - os.system("rm *png") - - def printmeta(self, pp, filename="output2.pdf", debug=False): - import os - from pyPdf import PdfFileWriter, PdfFileReader - - PAGE_HEIGHT = defaultPageSize[1] - styles = getSampleStyleSheet() - Title = "BOUT++ Results" - Author = "Dmitry Meyerson" - URL = "" - email = "dmitry.meyerson@gmail.com" - Abstract = """This document highlights some results from BOUT++ simulation""" - Elements = [] - HeaderStyle = styles["Heading1"] - ParaStyle = styles["Normal"] - PreStyle = styles["Code"] - - def header( - txt, style=HeaderStyle, klass=Paragraph, sep=0.3 - ): # return styled text with a space - s = Spacer(0.2 * inch, sep * inch) - para = klass(txt, style) - sect = [s, para] - result = KeepTogether(sect) - return result - - def p(txt): # wrapper for header - return header(txt, style=ParaStyle, sep=0.1) - - def pre(txt): # return styled text with a space - s = Spacer(0.1 * inch, 0.1 * inch) - p = Preformatted(txt, PreStyle) - precomps = [s, p] - result = KeepTogether(precomps) - return result - - def graphout(name, datain, xaxis=None): - if xaxis is None: - xaxis = list(range(datain.size)) - if xlabel is None: - xlabel = "" - if ylabel is None: - ylabel = "" - - drawing = Drawing(400, 200) - # data = [ - # ((1,1), (2,2), (2.5,1), (3,3), (4,5)), - # ((1,2), (2,3), (2.5,2), (3.5,5), (4,6)) - # ] - dataview = [tuple([(xaxis[i], datain[i]) for i in range(datain.size)])] - lp = LinePlot() - lp.x = 50 - lp.y = 50 - lp.height = 125 - lp.width = 300 - lp.data = dataview - lp.xValueAxis.xLabelFormat = "{mmm} {yy}" - lp.lineLabels.fontSize = 6 - lp.lineLabels.boxStrokeWidth = 0.5 - lp.lineLabels.visible = 1 - lp.lineLabels.boxAnchor = "c" - # lp.joinedLines = 1 - # lp.lines[0].symbol = makeMarker('FilledCircle') - # lp.lines[1].symbol = makeMarker('Circle') - # lp.lineLabelFormat = '%2.0f' - # lp.strokeColor = colors.black - # lp.xValueAxis.valueMin = min(xaxis) - # lp.xValueAxis.valueMax = max(xaxis) - # lp.xValueAxis.valueSteps = xaxis - # lp.xValueAxis.labelTextFormat = '%2.1f' - # lp.yValueAxis.valueMin = min(datain) - # lp.yValueAxis.valueMax = max(datain) - # lp.yValueAxis.valueSteps = [1, 2, 3, 5, 6] - drawing.add(lp) - return drawing - - def go(): - doc = SimpleDocTemplate("meta.pdf") - doc.build(Elements) - - mytitle = header(Title) - myname = header(Author, sep=0.1, style=ParaStyle) - mysite = header(URL, sep=0.1, style=ParaStyle) - mymail = header(email, sep=0.1, style=ParaStyle) - abstract_title = header("ABSTRACT") - myabstract = p(Abstract) - head_info = [mytitle, myname, mysite, mymail, abstract_title, myabstract] - Elements.extend(head_info) - - meta_title = header("metadata", sep=0) - metasection = [] - metasection.append(meta_title) - - for i, elem in enumerate(self.meta): - # if type(self.meta[elem]) != type(np.array([])): - - print(elem, type(self.meta[elem])) - - if type(self.meta[elem]) == type({}): - print("{}") - data = np.array(self.meta[elem]["v"]) - unit_label = str(self.meta[elem]["u"]) - else: - data = np.array(self.meta[elem]) - unit_label = "" - - xaxis = np.squeeze(self.meta["Rxy"]["v"][:, old_div(self.ny, 2)]) - - if data.shape == (self.nx, self.ny): - datastr = np.squeeze(data[:, old_div(self.ny, 2)]) - # metasection.append(graphout('stuff',datastr,xaxis=xaxis)) - # metasection.append(RL_Plot(datastr,xaxis)) - - metasection.append(RL_Plot(datastr, xaxis, linelabel=str(elem))) - # metasection.append(RL_Plot(datastr,xaxis,xlabel='xlabel')) - elif data.shape == self.nx: - datastr = data - # metasection.append(graphout('stuff',datastr,xaxis=xaxis)) - # metasection.append(RL_Plot(datastr,xaxis,linelabel=str(elem))) - elif data.shape == (1,): - data = data[0] - metasection.append( - header( - str(elem) + ": " + str(data) + " " + unit_label, - sep=0.1, - style=ParaStyle, - ) - ) - else: - print(elem, data, data.shape) - metasection.append( - header( - str(elem) + ": " + str(data) + " " + unit_label, - sep=0.1, - style=ParaStyle, - ) - ) - - src = KeepTogether(metasection) - Elements.append(src) - - cxxtitle = header("Equations in CXX") - cxxsection = [] - # print self.cxx - cxxsection.append(header(self.cxx[0], sep=0.1, style=ParaStyle)) - cxxsrc = KeepTogether(cxxsection) - - Elements.append(cxxsrc) - # for i,elem in enumerate(self.cxx): - # if type(self.meta[elem])== type({}): - # print elem #np.array(self.meta[elem]['v']).shape() - # if np.array(self.meta[elem]['v']).shape == (self.nx,self.ny): - # datastr = str(self.meta[elem]['v'][:,self.ny/2]) - # metasection.append(graphout('stuff', - # self.meta[elem]['v'][:,self.ny/2])) - # else: - # datastr = str(self.meta[elem]['v']) - # metasection.append(header(str(elem)+': '+datastr - # + ' '+ str(self.meta[elem]['u']), - # sep=0.1, style=ParaStyle)) - - if debug: - return Elements - go() - - output = PdfFileWriter() - metapdf = PdfFileReader(file("meta.pdf", "rb")) - mainpdf = PdfFileReader(file("output.pdf", "rb")) - - for i in range(0, metapdf.getNumPages()): - output.addPage(metapdf.getPage(i)) - - for i in range(0, mainpdf.getNumPages()): - output.addPage(mainpdf.getPage(i)) - - outputFile = filename - outputStream = file(outputFile, "wb") - output.write(outputStream) - outputStream.close() - print("Consolidation complete.") - - -class subset(LinResDraw): - def __init__(self, alldb, key, valuelist, model=False): - selection = ListDictFilt(alldb, key, valuelist) - if len(selection) != 0: - LinRes.__init__(self, selection) - self.skey = key - if model == True: - self.model() - else: - LinRes.__init__(self, alldb) - if model == True: - self.model() diff --git a/tools/pylib/post_bout/pb_nonlinear.py b/tools/pylib/post_bout/pb_nonlinear.py deleted file mode 100644 index 3fb726d4f8..0000000000 --- a/tools/pylib/post_bout/pb_nonlinear.py +++ /dev/null @@ -1,99 +0,0 @@ -from __future__ import absolute_import -from __future__ import division -from builtins import range -from past.utils import old_div - -# some function to plot nonlinear stuff -from .pb_corral import LinRes -from .ListDict import ListDictKey, ListDictFilt -import numpy as np - -import matplotlib.pyplot as plt -from matplotlib import cm -import matplotlib.artist as artist -import matplotlib.ticker as ticker -import matplotlib.pyplot as plt -import matplotlib.patches as patches -from matplotlib.figure import Figure -from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas -from matplotlib.backends.backend_pdf import PdfPages - -from reportlab.platypus import * -from reportlab.lib.styles import getSampleStyleSheet -from reportlab.rl_config import defaultPageSize -from reportlab.lib.units import inch -from reportlab.graphics.charts.linecharts import HorizontalLineChart -from reportlab.graphics.shapes import Drawing -from reportlab.graphics.charts.lineplots import LinePlot -from reportlab.graphics.widgets.markers import makeMarker -from reportlab.lib import colors - -from replab_x_vs_y import RL_Plot -from matplotlib.ticker import ScalarFormatter, FormatStrFormatter, MultipleLocator - - -class NLinResDraw(LinRes): - def __init__(self, alldb): - LinRes.__init__(self, alldb) - - def plotnlrhs( - self, - pp, - field="Ni", - yscale="linear", - clip=0, - xaxis="t", - xscale="linear", - xrange=1, - ): - colors = ["b", "g", "r", "c", "m", "y", "k", "b", "g", "r", "c", "m", "y", "k"] - - Modes = subset(self.db, "field", [field]) # pick field - comp = "ave" - - fig1 = plt.figure() - adj = fig1.subplots_adjust(hspace=0.4, wspace=0.4) - fig1.suptitle("Nonlinear contribution for " + field) - props = dict(alpha=0.8, edgecolors="none") - Nplots = self.nrun - - k = 0 - for j in list(set(Modes.path).union()): - s = subset(Modes.db, "path", [j]) # pick a run folder - many modes - dz = s.dz[0] - data = s.ave[0]["nl"] - x = np.array(list(range(data.size))) - - ax = fig1.add_subplot(round(old_div(Nplots, 2.0) + 1.0), 2, k + 1) - ax.set_ylabel(r"$\frac{ddt_N}{ddt}$", fontsize=12, rotation="horizontal") - k += 1 - ax.grid(True, linestyle="-", color=".75") - try: - ax.set_yscale(yscale, linthreshy=1e-13) - except: - ax.set_yscale("linear") - i = 1 - ax.plot(x, data.flatten(), c=cm.jet(0.2 * i), linestyle="-") - - # data = np.array(ListDictKey(s.db,comp)) #pick component should be ok for a fixed dz key - - # we are not interested in looping over all modes - - fig1.savefig(pp, format="pdf") - plt.close(fig1) - - # return 0 - - -class subset(NLinResDraw): - def __init__(self, alldb, key, valuelist, model=False): - selection = ListDictFilt(alldb, key, valuelist) - if len(selection) != 0: - LinRes.__init__(self, selection) - self.skey = key - if model == True: - self.model() - else: - LinRes.__init__(self, alldb) - if model == True: - self.model() diff --git a/tools/pylib/post_bout/pb_present.py b/tools/pylib/post_bout/pb_present.py deleted file mode 100644 index 64fcaf1ec6..0000000000 --- a/tools/pylib/post_bout/pb_present.py +++ /dev/null @@ -1,213 +0,0 @@ -from __future__ import print_function -from __future__ import absolute_import -from builtins import str -from builtins import range -from .pb_draw import LinResDraw, subset -from .pb_corral import LinRes -from .pb_nonlinear import NLinResDraw -from pb_transport import Transport - -import numpy as np -import matplotlib.pyplot as plt - -import matplotlib.pyplot as plt -from matplotlib.figure import Figure -from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas -from matplotlib.backends.backend_pdf import PdfPages -import matplotlib.artist as artist -import matplotlib.ticker as ticker - -# from matplotlib.ticker import FuncFormatter -# from matplotlib.ticker import ScalarFormatter - -from reportlab.platypus import * -from reportlab.lib.styles import getSampleStyleSheet -from reportlab.rl_config import defaultPageSize -from reportlab.lib.units import inch -from reportlab.graphics.charts.linecharts import HorizontalLineChart -from reportlab.graphics.shapes import Drawing -from reportlab.graphics.charts.lineplots import LinePlot -from reportlab.graphics.widgets.markers import makeMarker -from reportlab.lib import colors - -from replab_x_vs_y import RL_Plot - -# for movie making -from multiprocessing import Queue, Pool -import multiprocessing -import subprocess - -# uses LinResDraw to make a pdf - - -class LinResPresent(LinResDraw, NLinResDraw, Transport): - def __init__(self, alldb): - LinResDraw.__init__(self, alldb) - NLinResDraw.__init__(self, alldb) - Transport.__init__(self, alldb) - - def show( - self, - filter=True, - quick=False, - pdfname="output2.pdf", - debug=False, - spectrum_movie=False, - ): - colors = ["b", "g", "r", "c", "m", "y", "k", "b", "g", "r", "c", "m", "y", "k"] - pp = PdfPages("output.pdf") - - # start by removing modes above the maxN threshold - modelist = [] - [ - modelist.append(list(self.modeid[p])) - for p in range(self.nmodes) - if self.mn[p][1] <= self.maxN[p] - ] - - s = subset(self.db, "modeid", modelist) - - try: - # fig = Figure(figsize=(6,6)) - # fig = plt.figure() - dz0 = list(set(s.dz).union())[0] - ss = subset(s.db, "dz", [dz0]) - - # show initial condition and the first step after - s.plotvsK( - pp, - yscale="log", - xscale="log", - t=[0, 1, -1], - overplot=False, - comp="amp", - trans=True, - ) - - if spectrum_movie: - ss.savemovie() - - except: - print("no scatter") - # 2D true NM spectrum with color code and boxes around spectral res regions log scale - - plt.figure() - i = 0 - for j in list( - set(s.dz).union() - ): # looping over runs, over unique 'dz' key values - ss = subset(s.db, "dz", [j]) # subset where dz = j - plt.scatter(ss.MN[:, 1], ss.MN[:, 0], c=colors[i]) - plt.annotate(str(j), (ss.MN[0, 1], ss.MN[0, 0])) - i += 1 - - plt.title(" Ni spectrum at t=0, all x") - plt.ylabel("M -parallel") - plt.xlabel("N - axisymmteric") - plt.xscale("log") - plt.grid(True, linestyle="-", color=".75") - - try: - plt.savefig(pp, format="pdf") - except: - print("FAILED TO save 1st part") - - plt.close() - - # for elem in self.meta['evolved']['v']: - # s.plotnl(pp - - if self.meta["nonlinear"]["v"] == "true": - self.plotnlrhs(pp) - - if self.meta["transport"] == "true": - self.plotnlrms(pp) - - for elem in self.meta["evolved"]: - s.plotmodes( - pp, - yscale="symlog", - comp="phase", - linestyle=".", - field=elem, - summary=False, - ) - s.plotmodes(pp, yscale="symlog", field=elem, summary=False) - print(elem) - try: - s.plotmodes( - pp, yscale="symlog", field=elem, comp="gamma_i", summary=False - ) - except: - print("gamma_i plot for " + elem + " failed") - - # s.plotmodes(pp,yscale='symlog',summary=False) - - modelist = [] - # maxZ = - # [modelist.append([1,p+1]) for p in range(maxZ-1)] - [ - modelist.append(list(self.modeid[p])) - for p in range(self.nmodes) - if self.mn[p][1] <= self.maxN[p] - ] - ss = subset(s.db, "mn", modelist) - - if debug: # just a few problematic slides - fig1 = plt.figure() - pp_bug = PdfPages("debug.pdf") - # ss.plotmodes(pp_bug,yscale='symlog',comp='phase',summary=False) - s.plotfreq2(pp_bug, xscale="log", yscale="symlog", overplot=True) - ss.plotgamma(pp_bug, xscale="log", yscale="symlog", overplot=True) - ss.plottheory(pp_bug) - ss.plottheory(pp_bug, comp="freq") - fig1.savefig(pp_bug, format="pdf") - pp_bug.close() - pp.close() - return 0 - - dir(ss) - ss.plotmodes(pp, yscale="log", debug=True, summary=False) - ss.plotmodes(pp, yscale="symlog", comp="phase", summary=False) - ss.plotmodes(pp, yscale="symlog", comp="phase", field="rho", summary=False) - print(dir(ss)) - - # ss.plotmodes(pp,yscale='log',comp='phase',clip=True) - - # ss.plotfreq2(pp,xscale='log',yscale='linear',overplot=False) - for elem in self.meta["evolved"]: - ss.plotfreq2( - pp, xscale="log", yscale="symlog", field=elem, overplot=True, trans=True - ) - - # ss.plotfreq2(pp,xscale='log',yscale='symlog',field='rho',overplot=True) - - if quick == True: - pp.close() - s.printmeta(pp) - - # plt.savefig(pp, format='pdf') - return 0 - - all_fields = list(set(s.field).union()) - - s.plotgamma(pp, xscale="log", yscale="linear", overplot=True, trans=True) - - s.plotgamma(pp, yscale="symlog", xscale="log", overplot=True) - s.plotgamma(pp, yscale="symlog", xscale="log", field="rho", overplot=True) - - try: - s.plotfreq2(pp, xscale="log", yscale="linear", overplot=True) - # s.plotfreq2(pp,xscale='log',yscale='symlog',overplot=False) - s.plotfreq2(pp, xscale="log", yscale="symlog", field="rho", overplot=True) - - # s.plotfreq2(pp,xscale='log',yscale='linear') - except: - print("something terrible") - - s.plotradeigen(pp, yscale="linear") - # s.plotradeigen(pp,field ='Vi',yscale='linear') - s.plotradeigen(pp, field="rho", yscale="log") - - pp.close() - s.printmeta(pp, filename=pdfname) # append a metadata header diff --git a/tools/pylib/post_bout/read_cxx.py b/tools/pylib/post_bout/read_cxx.py deleted file mode 100644 index eda88aac5b..0000000000 --- a/tools/pylib/post_bout/read_cxx.py +++ /dev/null @@ -1,139 +0,0 @@ -from builtins import range -from read_grid import read_grid -from ordereddict import OrderedDict -import numpy as np -import string -import re - - -def findlowpass(cxxstring): - ##p1="lowPass\(.*\)" - p1 = "lowPass\(.*\,(.*)\)" - maxN = np.array(re.findall(p1, cxxstring)) - # print substrings - - # p2=("[0-9]") - - # maxN = np.array([re.findall(p2,elem) for elem in substrings]).flatten() - - if maxN.size == 0: - return 100 - else: - output = int(min(maxN)) - if output == 0: - return 20 - else: - return output - - -def no_comment_cxx(path=".", boutcxx="physics_code.cxx.ref"): - # print 'no_comment' - boutcxx = path + "/" + boutcxx - # boutcxx = open(boutcxx,'r').readlines() - f = open(boutcxx, "r") - boutcxx = f.read() - f.close() - - start = string.find(boutcxx, "/*") - end = string.find(boutcxx, "*/") + 2 - - s = boutcxx[0:start] - for i in range(string.count(boutcxx, "/*")): - start = string.find(boutcxx, "/*", end) - s = s + boutcxx[end + 1 : start - 1] - - end = string.find(boutcxx, "*/", end) + 2 - - s = s + boutcxx[end + 1 :] - - # pattern = "\n \s* \(//)* .* \n" #pattern for a section start [All],[Ni], etc - pattern = "\n+.*;" # everythin - pattern = re.compile(pattern) - result = re.findall(pattern, s) - - # print result - - nocomment = [] - for elem in result: - # print elem - elem = elem.lstrip() - stop = elem.find("//") - # print start,stop - - if stop > 0: - nocomment.append(elem[0:stop]) - elif stop == -1: - nocomment.append(elem) - - # result = pattern.match(val) - # start = string.find(z,'\n //') - # end =string.find(boutcxx,'*/')+2 - # print nocomment - - return nocomment - - -def get_evolved_cxx(cxxfile=None): - if cxxfile is None: - cxxfile = no_comment_cxx() - - # s = cxxfile - # section_0 = string.find(s,'int physics_run(BoutReal t)') - # section_1 = string.find(s,'return',section_0) - # s = s[section_0:section_1] - temp = [] - - for x in cxxfile: - i = x.find("bout_solve(") - # print i,x - if i != -1: - comma_i = x[i::].find('"') - comma_j = x[i::].rfind('"') - # print x[i+comma_i:i+comma_j+1] - temp.append(x[i + comma_i + 1 : i + comma_j]) - - evolved = [] - [evolved.append(x) for x in set(temp)] - return np.array(evolved) - - -def read_cxx(path=".", boutcxx="physics_code.cxx.ref", evolved=""): - # print path, boutcxx - boutcxx = path + "/" + boutcxx - # boutcxx = open(boutcxx,'r').readlines() - f = open(boutcxx, "r") - boutcxx = f.read() - f.close() - - # start by stripping out all comments - # look at the 1st character of all list elements - # for now use a gross loop, vectorize later - - start = string.find(boutcxx, "/*") - end = string.find(boutcxx, "*/") + 2 - - s = boutcxx[0:start] - for i in range(string.count(boutcxx, "/*")): - start = string.find(boutcxx, "/*", end) - s = s + boutcxx[end + 1 : start - 1] - - end = string.find(boutcxx, "*/", end) + 2 - - s = s + boutcxx[end + 1 :] - - section_0 = string.find(s, "int physics_run(BoutReal t)") - section_1 = string.find(s, "return", section_0) - s = s[section_0:section_1] - - tmp = open("./read_cxx.tmp", "w") - tmp.write(s) - tmp.close() - tmp = open("./read_cxx.tmp", "r") - - cxxlist = "" - - for line in tmp: - if line[0] != "//" and line.isspace() == False: - cxxlist = cxxlist + line.split("//")[0] - - return cxxlist diff --git a/tools/pylib/post_bout/read_inp.py b/tools/pylib/post_bout/read_inp.py deleted file mode 100644 index 87de7ddf3a..0000000000 --- a/tools/pylib/post_bout/read_inp.py +++ /dev/null @@ -1,433 +0,0 @@ -from __future__ import print_function -from __future__ import absolute_import -from __future__ import division -from builtins import str -from past.utils import old_div -from builtins import object -from read_grid import read_grid -from ordereddict import OrderedDict -import numpy as np -from boututils.file_import import file_import -from .read_cxx import * - - -def read_inp(path="", boutinp="BOUT.inp"): - boutfile = path + "/" + boutinp - boutinp = open(boutfile, "r").readlines() - - # start by stripping out all comments - # look at the 1st character of all list elements - # for now use a gross loop, vectorize later - boutlist = [] - - for i, val in enumerate(boutinp): - if val[0] != "#" and val.isspace() == False: - boutlist.append(val.split("#")[0]) - - return boutlist - - -def parse_inp(boutlist): - import re - from ordereddict import OrderedDict - - if not boutlist: - return 0 - - # boutdic={} unordered standard dict - boutdic = OrderedDict() - - # regex is messy see http://docs.python.org/howto/regex.html#regex-howto - pattern = "\[\S*\]" # pattern for a section start [All],[Ni], etc - - pattern = re.compile(pattern) - - boutdic["[main]"] = {} - current = "[main]" - - for i, val in enumerate(boutlist): - # print i,val - result = pattern.match(val) - # while the current value is not a new section name add everything to the current section - - if result is None: - # print val - key, value = val.split("=") - value = value.replace('"', "") - # print current, key,value - - boutdic[current][key.strip()] = value.strip() - else: - boutdic[result.group()] = {} - current = result.group() - - return boutdic - - -def read_log(path=".", logname="status.log"): - print("in read_log") - import re - from ordereddict import OrderedDict - - # logfile = path+'/'+logname - logfile = logname - print(logfile) - logcase = open(logfile, "r").readlines() - - # start by stripping out all comments - # look at the 1st character of all list elements - # for now use a gross loop, vectorize later - loglist = [] - - for i, val in enumerate(logcase): - if val[0] != "#" and val.isspace() == False: - loglist.append(val.split("#")[0]) - - if not loglist: - return 0 - - logdict = OrderedDict() - logdict["runs"] = [] - # print len(loglist) - print(loglist) - # print loglist[len(loglist)-1] == 'last one\n' - - # last = loglist.pop().rstrip() - - # logdict['done'] = last == 'done' - - logdict["current"] = loglist.pop().rstrip() - for i, val in enumerate(loglist): - print(val) - logdict["runs"].append(val.rstrip()) - - logdict["runs"].append(logdict["current"]) - - # print logdict - return logdict - - -def metadata(inpfile="BOUT.inp", path=".", v=False): - filepath = path + "/" + inpfile - print(filepath) - inp = read_inp(path=path, boutinp=inpfile) - inp = parse_inp(inp) # inp file - print(path) - outinfo = file_import(path + "/BOUT.dmp.0.nc") # output data - - try: - print(path) - cxxinfo = no_comment_cxx(path=path, boutcxx="physics_code.cxx.ref") - # evolved = get_evolved_cxx(cxxinfo) - fieldkeys = get_evolved_cxx(cxxinfo) - fieldkeys = ["[" + elem + "]" for elem in fieldkeys] - except: - print("cant find the cxx file") - - # gridoptions = {'grid':grid,'mesh':mesh} - if "[mesh]" in list(inp.keys()): - # IC = outinfo - IC = read_grid(path + "/BOUT.dmp.0.nc") # output data again - elif "grid" in inp["[main]"]: - gridname = inp["[main]"]["grid"] - try: - IC = read_grid(gridname) # have to be an ansoulte file path for now - print("IC: ", type(IC)) - # print IC.variables - # print gridname - except: - # print gridname - print("Fail to load the grid file") - # print IC - - # print gridname - # print len(IC) - # print IC - - evolved = [] - collected = [] - ICscale = [] - - # fieldkeys = ['[Ni]','[Te]','[Ti]','[Vi]','[rho]', - # '[Ajpar]','[Apar]','[vEBx]','[vEBy]','[vEBz]', - # '[jpar]','[phi]'] - - # construct fieldkeys from cxx info - # fieldkeys = ['['+x+']' for x in evolved] - # fieldkeys = evolved - - # just look ahead and see what 3D fields have been output - available = np.array([str(x) for x in outinfo]) - a = np.array([(len(outinfo[x].shape) == 4) for x in available]) - available = available[a] - - defaultIC = float(inp["[All]"].get("scale", 0.0)) - - # print inp.keys() - - # figure out which fields are evolved - print(fieldkeys) - - for section in list(inp.keys()): # loop over section keys - print("section: ", section) - if section in fieldkeys: # pick the relevant sections - print(section) - # print inp[section].get('evolve','True') - # rint (inp[section].get('evolve','True')).lower().strip() - if ( - inp[section].get("evolve", "True").lower().strip() == "true" - ): # and section[1:-1] in available : - print("ok reading") - evolved.append(section.strip("[]")) - ICscale.append(float(inp[section].get("scale", defaultIC))) - - if inp[section].get("collect", "False").lower().strip() == "true": - collected.append(section.strip("[]")) - - try: - if inp["[physics]"].get("transport", "False").lower().strip() == "true": - vEBstr = ["vEBx", "vEBy", "vEBz", "vEBrms"] - [collected.append(item) for item in vEBstr] - except: - print("no [physics] key") - - meta = OrderedDict() - - class ValUnit(object): - def __init__(self, value=0, units=""): - self.u = units - self.v = value - - def todict(self): - return {"u": self.u, "v": self.v} - - # def decode_valunit(d): - - def ToFloat(metaString): - try: - return float(metaString) - except ValueError: - return metaString - - # meta['evolved'] = ValUnit(evolved,'') - meta["evolved"] = evolved - meta["collected"] = collected - meta["IC"] = np.array(ICscale) - d = {} - - print("evolved: ", evolved) - - # read meta data from .inp file, this is whre most metadata get written - for section in list(inp.keys()): - if ("evolve" not in inp[section]) and ( - "first" not in inp[section] - ): # hacky way to exclude some less relevant metadata - for elem in list(inp[section].keys()): - meta[elem] = ValUnit(ToFloat(inp[section][elem])) - d[elem] = np.array(ToFloat(inp[section][elem])) - - # read in some values from the grid(IC) and scale them as needed - norms = { - "Ni0": ValUnit(1.0e14, "cm^-3"), - "bmag": ValUnit(1.0e4, "gauss"), - "Ni_x": ValUnit(1.0e14, "cm^-3"), - "Te_x": ValUnit(1.0, "eV"), - "Ti_x": ValUnit(1.0, "eV"), - "Rxy": ValUnit(1, "m"), - "Bxy": ValUnit(1.0e4, "gauss"), - "Bpxy": ValUnit(1.0e4, "gauss"), - "Btxy": ValUnit(1.0e4, "gauss"), - "Zxy": ValUnit(1, "m"), - "dlthe": ValUnit(1, "m"), - "dx": ValUnit(1, "m"), - "hthe0": ValUnit(1, "m"), - } - - availkeys = np.array([str(x) for x in outinfo]) - tmp1 = np.array([x for x in availkeys]) - # b = np.array([x if x not in available for x in a]) - tmp2 = np.array([x for x in tmp1 if x not in available]) - static_fields = np.array([x for x in tmp2 if x in list(norms.keys())]) - # static_fields = tmp2 - - # print availkeys - # print meta.keys() - # print IC.variables.keys() - # print tmp1 - # print tmp2 - - for elem in static_fields: - print("elem: ", elem) - meta[elem] = ValUnit(IC.variables[elem][:] * norms[elem].v, norms[elem].u) - d[elem] = np.array(IC.variables[elem][:] * norms[elem].v) - - for elem in IC.variables: - if elem not in meta: - if elem in list(norms.keys()): - meta[elem] = ValUnit( - IC.variables[elem][:] * norms[elem].v, norms[elem].u - ) - d[elem] = np.array(IC.variables[elem][:] * norms[elem].v) - else: - meta[elem] = IC.variables[elem][:] - d[elem] = IC.variables[elem][:] - - # print d.keys() - - # if case some values are missing - default = { - "bmag": 1, - "Ni_x": 1, - "NOUT": 100, - "TIMESTEP": 1, - "MZ": 32, - "AA": 1, - "Zeff": ValUnit(1, ""), - "ZZ": 1, - "zlowpass": 0.0, - "transport": False, - } - diff = set(default.keys()).difference(set(d.keys())) - - for elem in diff: - # print 'diff: ',elem - meta[elem] = default[elem] - d[elem] = np.array(default[elem]) - - # print meta.keys() - # print d.keys() - - # print meta['zlowpass'] - - if meta["zlowpass"] != 0: - print(meta["MZ"].v, meta["zlowpass"].v) - meta["maxZ"] = int(np.floor(meta["MZ"].v * meta["zlowpass"].v)) - else: - meta["maxZ"] = 5 - - # meta['nx'] = nx - # meta['ny']= ny - meta["dt"] = meta["TIMESTEP"] - - # nx,ny = d['Rxy'].shape - - # print meta['AA'].v - - meta["rho_s"] = ValUnit( - 1.02e2 * np.sqrt(d["AA"] * d["Te_x"]) / (d["ZZ"] * d["bmag"]), "cm" - ) # ion gyrorad at T_e, in cm - meta["rho_i"] = ValUnit( - 1.02e2 * np.sqrt(d["AA"] * d["Ti_x"]) / (d["ZZ"] * d["bmag"]), "cm" - ) - meta["rho_e"] = ValUnit(2.38 * np.sqrt(d["Te_x"]) / (d["bmag"]), "cm") - - meta["fmei"] = ValUnit(1.0 / 1836.2 / d["AA"]) - - meta["lambda_ei"] = 24.0 - np.log(old_div(np.sqrt(d["Ni_x"]), d["Te_x"])) - meta["lambda_ii"] = 23.0 - np.log( - d["ZZ"] ** 3 * np.sqrt(2.0 * d["Ni_x"]) / (d["Ti_x"] ** 1.5) - ) # - - meta["wci"] = 1.0 * 9.58e3 * d["ZZ"] * d["bmag"] / d["AA"] # ion gyrofrteq - meta["wpi"] = ( - 1.32e3 * d["ZZ"] * np.sqrt(old_div(d["Ni_x"], d["AA"])) - ) # ion plasma freq - - meta["wce"] = 1.78e7 * d["bmag"] # electron gyrofreq - meta["wpe"] = 5.64e4 * np.sqrt(d["Ni_x"]) # electron plasma freq - - meta["v_the"] = 4.19e7 * np.sqrt(d["Te_x"]) # cm/s - meta["v_thi"] = 9.79e5 * np.sqrt(old_div(d["Ti_x"], d["AA"])) # cm/s - meta["c_s"] = 9.79e5 * np.sqrt(5.0 / 3.0 * d["ZZ"] * d["Te_x"] / d["AA"]) # - meta["v_A"] = 2.18e11 * np.sqrt(old_div(1.0, (d["AA"] * d["Ni_x"]))) - - meta["nueix"] = 2.91e-6 * d["Ni_x"] * meta["lambda_ei"] / d["Te_x"] ** 1.5 # - meta["nuiix"] = ( - 4.78e-8 - * d["ZZ"] ** 4.0 - * d["Ni_x"] - * meta["lambda_ii"] - / d["Ti_x"] ** 1.5 - / np.sqrt(d["AA"]) - ) # - meta["nu_hat"] = meta["Zeff"].v * meta["nueix"] / meta["wci"] - - meta["L_d"] = 7.43e2 * np.sqrt(old_div(d["Te_x"], d["Ni_x"])) - meta["L_i_inrt"] = ( - 2.28e7 * np.sqrt(old_div(d["AA"], d["Ni_x"])) / d["ZZ"] - ) # ion inertial length in cm - meta["L_e_inrt"] = 5.31e5 * np.sqrt(d["Ni_x"]) # elec inertial length in cm - - meta["Ve_x"] = 4.19e7 * d["Te_x"] - - meta["R0"] = old_div((d["Rxy"].max() + d["Rxy"].min()), 2.0) - - print(d["Rxy"].mean(1)) - print(d["ZMAX"]) - print(d["ZMIN"]) - meta["L_z"] = ( - 1e2 * 2 * np.pi * d["Rxy"].mean(1) * (d["ZMAX"] - d["ZMIN"]) - ) # in cm toroidal range - meta["dz"] = d["ZMAX"] - d["ZMIN"] - - # meta['lbNorm']=meta['L_z']*(d['Bpxy']/d['Bxy']).mean(1) #-binormal coord range [cm] - meta["lbNorm"] = meta["L_z"] * (old_div(d["Bxy"], d["Bpxy"])).mean(1) - - # meta['zPerp']=np.array(meta['lbNorm']).mean*np.array(range(d['MZ']))/(d['MZ']-1) - # let's calculate some profile properties - dx = np.gradient(d["Rxy"])[0] - meta["L"] = ( - 1.0 - * 1e2 - * dx - * (meta["Ni0"].v) - / np.gradient(meta["Ni0"].v)[0] - / meta["rho_s"].v - ) - - meta["w_Ln"] = old_div( - meta["c_s"], (np.min(abs(meta["L"])) * meta["wci"] * meta["rho_s"].v) - ) # normed to wci - - AA = meta["AA"].v - ZZ = d["ZZ"] - Te_x = d["Te_x"] - Ti_x = d["Ti_x"] - fmei = meta["fmei"].v - - meta["lpar"] = ( - 1e2 * ((old_div(d["Bxy"], d["Bpxy"])) * d["dlthe"]).sum(1) / meta["rho_s"].v - ) # -[normed], average over flux surfaces, parallel length - - # yes dlthe is always the vertical displacement - # dlthe = (hthe0*2 pi)/nz - # meta['lpar']=1e2*(d['Bxy']/d['Bpxy']).mean(1)*d['dlthe'].mean(1) #function of x - meta["sig_par"] = old_div(1.0, (fmei * 0.51 * meta["nu_hat"])) - # meta['heat_nue'] = ((2*np.pi/meta['lpar'])**2)/(fmei*meta['nu_hat']) - # kz_e = kz_i*(rho_e/rho_i) - # kz_s = kz_i*(rho_s/rho_i) - # kz_i = (TWOPI/L_z)*(indgen((*current_str).fft.nz+1))*rho_i - - # knorm = (TWOPI/lbNorm)*(indgen((*current_str).fft.nz+1))*rho_s - - # for now just translate - for elem in meta: - if type(meta[elem]).__name__ == "ValUnit": - meta[elem] = {"u": meta[elem].u, "v": meta[elem].v} - - print("meta: ", type(meta)) - return meta - - # meta['DZ'] =inp['[main]']['ZMAX']#-b['[main]']['ZMIN'] - # AA = inp['[2fluid]']['AA'] - # Ni0 = IC.variables['Ni0'][:]*1.e14 - # bmag = IC.variables['bmag'][:]*1.e4 #to cgs - # Ni_x = IC.variables['Ni_x'][:]*1.e14 # cm^-3 - # Te_x - - # rho_s = 1.02e2*sqrt(AA.v*Te_x.v)/ZZ.v/bmag.v - # rho_i - # rho_e - - -# for i,val in enumerate(boutlist): diff --git a/tools/pylib/post_bout/rms.py b/tools/pylib/post_bout/rms.py deleted file mode 100644 index 6a9bdb1929..0000000000 --- a/tools/pylib/post_bout/rms.py +++ /dev/null @@ -1,55 +0,0 @@ -from __future__ import division -from builtins import range -from past.utils import old_div - -### -# rms(f) : compute growth rate vs. time based on rms of bout variable f for all grid points -# plot_rms (x,y): plots the graph growth_rate vs. time for grid point x,y -### - - -import numpy as np -from pylab import plot, show, xlabel, ylabel, tight_layout -from boutdata.collect import collect - - -def rms(f): - nt = f.shape[0] - - ns = f.shape[1] - ne = f.shape[2] - nz = f.shape[3] - - ar = np.zeros([nz]) - - rms = np.zeros([nt, ns, ne]) - - for i in range(nt): - for j in range(ns): - for k in range(ne): - ar = f[i, j, k, :] - valav = np.sum(ar) - tot = np.sum(old_div(np.power(ar - valav, 2), nz)) - rms[i, j, k] = np.sqrt(tot) - return rms - - -def plot_rms(x, y): - s = plot(np.gradient(np.log(rmsp[:, x, y]))) - ylabel("$\gamma / \omega_A$", fontsize=25) - xlabel("Time$(\\tau_A)$", fontsize=25) - tight_layout() - return s - - -# test -if __name__ == "__main__": - path = "../../../examples/elm-pb/data" - - data = collect("P", path=path) - - rmsp = rms(data) - - plot_rms(34, 32) - tight_layout() - show() diff --git a/tools/tokamak_grids/all/grid2bout.py b/tools/tokamak_grids/all/grid2bout.py index da62a37aeb..6520e8f116 100644 --- a/tools/tokamak_grids/all/grid2bout.py +++ b/tools/tokamak_grids/all/grid2bout.py @@ -3,6 +3,7 @@ """ + from __future__ import print_function from numpy import max