diff --git a/.clang-tidy b/.clang-tidy index 556b8738f8..a142355fc4 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -9,6 +9,15 @@ CheckOptions: # otherwise this breaks `ASSERT` macros! - key: readability-simplify-boolean-expr.IgnoreMacros value: 'true' + + - key: misc-include-cleaner.IgnoreHeaders + value: 'petsc.*\.h;mpi\.h' + + - key: readability-qualified-auto.IgnoreAliasing + value: 'false' + + - key: readability-qualified-auto.AllowedTypes + value: 'MPI_Comm' --- Disabled checks and reasons: diff --git a/.github/workflows/black-fix.yml b/.github/workflows/black-fix.yml index 92866dfcc2..6c1bfed4a5 100644 --- a/.github/workflows/black-fix.yml +++ b/.github/workflows/black-fix.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: ref: ${{ github.head_ref }} diff --git a/.github/workflows/clang-format.yml b/.github/workflows/clang-format.yml index 49dfb31e25..e32c959cb2 100644 --- a/.github/workflows/clang-format.yml +++ b/.github/workflows/clang-format.yml @@ -8,10 +8,12 @@ on: jobs: clang-format: + # Release candidate branches tend to have big PRs which causes all sorts of problems + if: ${{ !endsWith(github.head_ref, '-rc') }} runs-on: ubuntu-latest steps: # Checkout the pull request branch, also include all history - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: ref: ${{ github.head_ref }} fetch-depth: 0 diff --git a/.github/workflows/clang-tidy-review.yml b/.github/workflows/clang-tidy-review.yml index 1e2f88d208..3f20db608f 100644 --- a/.github/workflows/clang-tidy-review.yml +++ b/.github/workflows/clang-tidy-review.yml @@ -5,9 +5,6 @@ on: paths: - '**.cxx' - '**.hxx' - branches-ignore: - # Release candidate branches tend to have big PRs which causes all sorts of problems - - 'v*rc' concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -15,14 +12,16 @@ concurrency: jobs: review: + # Release candidate branches tend to have big PRs which causes all sorts of problems + if: ${{ !endsWith(github.head_ref, '-rc') }} runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true - name: Run clang-tidy - uses: ZedThree/clang-tidy-review@v0.20.1 + uses: ZedThree/clang-tidy-review@v0.21.0 id: review with: build_dir: build @@ -47,4 +46,4 @@ jobs: -DBOUT_UPDATE_GIT_SUBMODULE=OFF - name: Upload clang-tidy fixes - uses: ZedThree/clang-tidy-review/upload@v0.20.1 + uses: ZedThree/clang-tidy-review/upload@v0.21.0 diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a1dac41a6b..1380d0ea8e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -52,7 +52,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Log in to the Container registry uses: docker/login-action@master diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index ea68e58c12..fc5e84662c 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -17,12 +17,12 @@ jobs: if: always() steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 submodules: true - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 - name: Install dependencies run: python -m pip install --upgrade pip && pip install --upgrade build && @@ -57,12 +57,12 @@ jobs: if: always() steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 submodules: true - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 - name: Install dependencies run: python -m pip install --upgrade pip && pip install --upgrade build && @@ -106,12 +106,12 @@ jobs: if: always() steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 submodules: true - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 - name: Install dependencies run: python -m pip install --upgrade pip && pip install --upgrade build && diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4153ebaefc..d6834eba6a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -168,11 +168,11 @@ jobs: libparpack2-dev libhypre-dev - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: '3.x' @@ -205,7 +205,7 @@ jobs: timeout-minutes: 120 runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: submodules: true - name: Build Fedora diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d346d47e8..41e3e2c47b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Changelog -## [v6.0.0](https://github.com/boutproject/BOUT-dev/tree/next) -[Full Changelog](https://github.com/boutproject/BOUT-dev/compare/v5.1.0...next) +## [v5.2.0](https://github.com/boutproject/BOUT-dev/tree/v5.2.0 + +[Full Changelog](https://github.com/boutproject/BOUT-dev/compare/v5.1.1...v5.2.0) ### Breaking changes @@ -16,6 +17,67 @@ confusing. Now, monitors are called with the current number of completed monitor-steps. +## Changes + +- Fixes for FreeBSD [\#3172][https://github.com/boutproject/BOUT-dev/pull/3172] ([tomc271][https://github.com/tomc271]) +- snes: Print a warning if the coloring is non-symmetric. [\#3159][https://github.com/boutproject/BOUT-dev/pull/3159] ([bendudson][https://github.com/bendudson]) +- Cmake fix from master [\#3152][https://github.com/boutproject/BOUT-dev/pull/3152] ([oparry-ukaea][https://github.com/oparry-ukaea]) +- Bump ZedThree/clang-tidy-review from 0.20.1 to 0.21.0 [\#3150][https://github.com/boutproject/BOUT-dev/pull/3150] ([ZedThree][https://github.com/ZedThree]) +- SNES solver: Added a PID controller to update the timestep [\#3146][https://github.com/boutproject/BOUT-dev/pull/3146] ([malamast][https://github.com/malamast]) +- Fix name clash in some examples and MMS tests [\#3145][https://github.com/boutproject/BOUT-dev/pull/3145] ([ZedThree][https://github.com/ZedThree]) +- Handle absolute paths to options file [\#3142][https://github.com/boutproject/BOUT-dev/pull/3142] ([bendudson][https://github.com/bendudson]) +- Revert eliminate hypre boundary equations [\#3136][https://github.com/boutproject/BOUT-dev/pull/3136] ([ZedThree][https://github.com/ZedThree]) +- CI: Switch to released fedora [\#3134][https://github.com/boutproject/BOUT-dev/pull/3134] ([dschwoerer][https://github.com/dschwoerer]) +- Generalise FakeMeshFixture to allow configurable grid spacing via templating [\#3132][https://github.com/boutproject/BOUT-dev/pull/3132] ([tomc271][https://github.com/tomc271]) +- Fixes for ELM-PB preconditioner [\#3128][https://github.com/boutproject/BOUT-dev/pull/3128] ([Steven-Roberts][https://github.com/Steven-Roberts]) +- Fix cast for new petsc [\#3117][https://github.com/boutproject/BOUT-dev/pull/3117] ([dschwoerer][https://github.com/dschwoerer]) +- Fix bug where ARKODE considered all problems linear [\#3114][https://github.com/boutproject/BOUT-dev/pull/3114] ([Steven-Roberts][https://github.com/Steven-Roberts]) +- cvode: Add linear_solver option [\#3112][https://github.com/boutproject/BOUT-dev/pull/3112] ([bendudson][https://github.com/bendudson]) +- periodicX communication fixes [\#3109][https://github.com/boutproject/BOUT-dev/pull/3109] ([bendudson][https://github.com/bendudson]) +- beuler solver timestep and Jacobian calculation [\#3107][https://github.com/boutproject/BOUT-dev/pull/3107] ([bendudson][https://github.com/bendudson]) +- Feature/snes stencil [\#3104][https://github.com/boutproject/BOUT-dev/pull/3104] ([seimtpow][https://github.com/seimtpow]) +- Add attributes to ADIOS2 output to "define" dimensions as names. We n… [\#3098][https://github.com/boutproject/BOUT-dev/pull/3098] ([pnorbert][https://github.com/pnorbert]) +- CI: Avoid issues with special characters [\#3090][https://github.com/boutproject/BOUT-dev/pull/3090] ([dschwoerer][https://github.com/dschwoerer]) +- CI: Fix clang format [\#3086][https://github.com/boutproject/BOUT-dev/pull/3086] ([dschwoerer][https://github.com/dschwoerer]) +- Small updates for FCI output [\#3085][https://github.com/boutproject/BOUT-dev/pull/3085] ([bendudson][https://github.com/bendudson]) +- Eliminate boundary equations to improve HYPRE solves [\#3082][https://github.com/boutproject/BOUT-dev/pull/3082] ([rfalgout][https://github.com/rfalgout]) +- Elm-pb example with relaxing phi [\#3081][https://github.com/boutproject/BOUT-dev/pull/3081] ([bendudson][https://github.com/bendudson]) +- CI: Show more output of dnf5 to help debugging [\#3071][https://github.com/boutproject/BOUT-dev/pull/3071] ([dschwoerer][https://github.com/dschwoerer]) +- Fix clang tidy review [\#3070][https://github.com/boutproject/BOUT-dev/pull/3070] ([ZedThree][https://github.com/ZedThree]) +- CMake: Bump downloaded SUNDIALS version [\#3067][https://github.com/boutproject/BOUT-dev/pull/3067] ([ZedThree][https://github.com/ZedThree]) +- Use isfinite, fix pvode linking [\#3063][https://github.com/boutproject/BOUT-dev/pull/3063] ([bendudson][https://github.com/bendudson]) +- Make iteration more robust and give more options in LaplaceNaulin [\#3061][https://github.com/boutproject/BOUT-dev/pull/3061] ([johnomotani][https://github.com/johnomotani]) +- Fixes zoidberg [\#3054][https://github.com/boutproject/BOUT-dev/pull/3054] ([dschwoerer][https://github.com/dschwoerer]) +- Fix finalise in boutpp [\#3053][https://github.com/boutproject/BOUT-dev/pull/3053] ([dschwoerer][https://github.com/dschwoerer]) +- Avoid some warnings for 3D Metrics [\#3052][https://github.com/boutproject/BOUT-dev/pull/3052] ([dschwoerer][https://github.com/dschwoerer]) +- Minor fixes for the python backend [\#3051][https://github.com/boutproject/BOUT-dev/pull/3051] ([dschwoerer][https://github.com/dschwoerer]) +- Cleanup BOUT_HOST_DEVICE qualifiers [\#3040][https://github.com/boutproject/BOUT-dev/pull/3040] ([ggeorgakoudis][https://github.com/ggeorgakoudis]) +- Deprecate options that are only used as default for other options [\#3038][https://github.com/boutproject/BOUT-dev/pull/3038] ([dschwoerer][https://github.com/dschwoerer]) +- Avoid using the wrong grid by accident [\#3036][https://github.com/boutproject/BOUT-dev/pull/3036] ([dschwoerer][https://github.com/dschwoerer]) +- Use PEP 625 compatible archive name (next) [\#3035][https://github.com/boutproject/BOUT-dev/pull/3035] ([dschwoerer][https://github.com/dschwoerer]) +- CI: Increase check level for debug run + unit test fixes [\#3033][https://github.com/boutproject/BOUT-dev/pull/3033] ([dschwoerer][https://github.com/dschwoerer]) +- Avoid `#define` conflict with sundials [\#3031][https://github.com/boutproject/BOUT-dev/pull/3031] ([dschwoerer][https://github.com/dschwoerer]) +- Ensure PETSc headers are included after `bout/petsclib.hxx` [\#3024][https://github.com/boutproject/BOUT-dev/pull/3024] ([ZedThree][https://github.com/ZedThree]) +- Fix minor HYPRE and ADIOS2 compilation issues [\#3022][https://github.com/boutproject/BOUT-dev/pull/3022] ([ZedThree][https://github.com/ZedThree]) +- Fix recompilation cascade [\#3021][https://github.com/boutproject/BOUT-dev/pull/3021] ([ZedThree][https://github.com/ZedThree]) +- Move `invert3x3` out of general purpose `utils.hxx` header [\#3018][https://github.com/boutproject/BOUT-dev/pull/3018] ([ZedThree][https://github.com/ZedThree]) +- Replace deprecated `boututils.file_import` [\#3017][https://github.com/boutproject/BOUT-dev/pull/3017] ([ZedThree][https://github.com/ZedThree]) +- CI: clang-tidy-review tweaks [\#3016][https://github.com/boutproject/BOUT-dev/pull/3016] ([ZedThree][https://github.com/ZedThree]) +- Backward Euler solver improvements [\#3009][https://github.com/boutproject/BOUT-dev/pull/3009] ([bendudson][https://github.com/bendudson]) +- Fix circular header dependency: mesh.hxx <-> griddata.hxx [\#3008][https://github.com/boutproject/BOUT-dev/pull/3008] ([ZedThree][https://github.com/ZedThree]) +- Fix exception message [\#3003][https://github.com/boutproject/BOUT-dev/pull/3003] ([dschwoerer][https://github.com/dschwoerer]) +- Ensure pointer is checked before dereferencing [\#3002][https://github.com/boutproject/BOUT-dev/pull/3002] ([dschwoerer][https://github.com/dschwoerer]) +- Fix: preserve regionID [\#3000][https://github.com/boutproject/BOUT-dev/pull/3000] ([dschwoerer][https://github.com/dschwoerer]) +- Lazy grid loading [\#2991][https://github.com/boutproject/BOUT-dev/pull/2991] ([dschwoerer][https://github.com/dschwoerer]) +- Fix compilation warnings with SUNDIALS 7.1.0 [\#2990][https://github.com/boutproject/BOUT-dev/pull/2990] ([Steven-Roberts][https://github.com/Steven-Roberts]) +- Add LC gitlab CI for GPU build/run tests [\#2989][https://github.com/boutproject/BOUT-dev/pull/2989] ([ggeorgakoudis][https://github.com/ggeorgakoudis]) +- BoutMask non-const operator[](Ind3D) [\#2988][https://github.com/boutproject/BOUT-dev/pull/2988] ([bendudson][https://github.com/bendudson]) +- Use consistently signed char [\#2987][https://github.com/boutproject/BOUT-dev/pull/2987] ([dschwoerer][https://github.com/dschwoerer]) +- naulin laplace: Acceptance tolerances after maxits [\#2983][https://github.com/boutproject/BOUT-dev/pull/2983] ([bendudson][https://github.com/bendudson]) +- Merge v5.1.1 into `next` [\#2978][https://github.com/boutproject/BOUT-dev/pull/2978] ([ZedThree][https://github.com/ZedThree]) +- CI: Bump all ubuntu images [\#2977][https://github.com/boutproject/BOUT-dev/pull/2977] ([ZedThree][https://github.com/ZedThree]) +- Read 2D variables into Field3D [\#2975][https://github.com/boutproject/BOUT-dev/pull/2975] ([bendudson][https://github.com/bendudson]) + ## [v5.1.1](https://github.com/boutproject/BOUT-dev/tree/v5.1.1) [Full Changelog](https://github.com/boutproject/BOUT-dev/compare/v5.1.0...v5.1.1) diff --git a/CITATION.cff b/CITATION.cff index 81f5c35e82..318fcd1406 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -197,11 +197,27 @@ authors: - family-names: Kryjak given-names: Mike -version: 5.1.1 -date-released: 2023-04-10 + - family-names: Powell + given-names: Seimon + - family-names: Ağgül + given-names: Mustafa + - family-names: Parry + given-names: Owen + - family-names: Podhorszki + given-names: Norbert + - family-names: Falgout + given-names: Rob + - family-names: Li + given-names: Nami + - family-names: Body + given-names: Tom + - family-names: Tsagkaridis + given-names: Malamas +version: 5.2.0 +date-released: 2025-10-10 repository-code: https://github.com/boutproject/BOUT-dev url: http://boutproject.github.io/ -doi: 10.5281/zenodo.13753882 +doi: 10.5281/zenodo.17313945 license: 'LGPL-3.0-or-later' references: - type: article diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e57495885..867d0bc31e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,8 +25,8 @@ endif() # CMake currently doesn't support proper semver # Set the version here, strip any extra tags to use in `project` # We try to use git to get a full description, inspired by setuptools_scm -set(_bout_previous_version "5.1.1") -set(_bout_next_version "5.2.0") +set(_bout_previous_version "5.2.0") +set(_bout_next_version "5.2.1") execute_process( COMMAND "git" describe --tags --match=v${_bout_previous_version} COMMAND sed -e s/${_bout_previous_version}-/${_bout_next_version}.dev/ -e s/-/+/ @@ -235,11 +235,13 @@ set(BOUT_SOURCES ./src/invert/laplace/impls/hypre3d/hypre3d_laplace.cxx ./src/invert/laplace/impls/hypre3d/hypre3d_laplace.hxx ./src/invert/laplace/invert_laplace.cxx + ./src/invert/laplacexy/impls/hypre/laplacexy-hypre.cxx + ./src/invert/laplacexy/impls/hypre/laplacexy-hypre.hxx + ./src/invert/laplacexy/impls/petsc/laplacexy-petsc.cxx + ./src/invert/laplacexy/impls/petsc/laplacexy-petsc.hxx + ./src/invert/laplacexy/impls/petsc2/laplacexy-petsc2.cxx + ./src/invert/laplacexy/impls/petsc2/laplacexy-petsc2.hxx ./src/invert/laplacexy/laplacexy.cxx - ./include/bout/invert/laplacexy2.hxx - ./src/invert/laplacexy2/laplacexy2.cxx - ./include/bout/invert/laplacexy2_hypre.hxx - ./src/invert/laplacexy2/laplacexy2_hypre.cxx ./src/invert/laplacexz/impls/cyclic/laplacexz-cyclic.cxx ./src/invert/laplacexz/impls/cyclic/laplacexz-cyclic.hxx ./src/invert/laplacexz/impls/petsc/laplacexz-petsc.cxx @@ -375,6 +377,7 @@ if (zoidberg_FOUND EQUAL 0) else() set(zoidberg_FOUND OFF) endif() +message(STATUS "Found Zoidberg for FCI tests: ${zoidberg_FOUND}") option(BOUT_GENERATE_FIELDOPS "Automatically re-generate the Field arithmetic operators from the Python templates. \ Requires Python3, clang-format, and Jinja2. Turn this OFF to skip generating them if, for example, \ diff --git a/README.md b/README.md index c2e035e924..c9e76a1ff4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![Build Status](https://github.com/boutproject/BOUT-dev/actions/workflows/tests.yml/badge.svg?branch=next)](https://github.com/boutproject/BOUT-dev/actions) [![License](https://img.shields.io/badge/license-LGPL-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0.en.html) [![py3comp](https://img.shields.io/badge/py3-compatible-brightgreen.svg)](https://img.shields.io/badge/py3-compatible-brightgreen.svg) -[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.13753882.svg)](https://doi.org/10.5281/zenodo.8369888) +[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.17313945.svg)](https://doi.org/10.5281/zenodo.17313945) ``` .______ ______ __ __ .___________. diff --git a/bin/bout-changelog-generator.py b/bin/bout-changelog-generator.py index cfb9a30bb0..d5ad11892e 100755 --- a/bin/bout-changelog-generator.py +++ b/bin/bout-changelog-generator.py @@ -1,4 +1,10 @@ #! /usr/bin/env python3 +# /// script +# requires-python = ">=3.12" +# dependencies = [ +# "pygithub", +# ] +# /// import argparse import os diff --git a/bin/update_citations.py b/bin/update_citations.py index c7771a3611..63f597f588 100755 --- a/bin/update_citations.py +++ b/bin/update_citations.py @@ -1,4 +1,11 @@ #!/usr/bin/env python3 +# /// script +# requires-python = ">=3.11" +# dependencies = [ +# "ruamel-yaml", +# "unidecode", +# ] +# /// import argparse import subprocess from collections import defaultdict @@ -242,6 +249,9 @@ def update_citations(): new_authors = [] for author in unrecognised_authors: + if " " not in author: + # This is just a GitHub handle, skip + continue first_name, last_name = author.rsplit(maxsplit=1) new_authors.append({"family-names": last_name, "given-names": first_name}) diff --git a/bin/update_version_number_in_files.py b/bin/update_version_number_in_files.py index 85df930aea..ec9a31bc32 100755 --- a/bin/update_version_number_in_files.py +++ b/bin/update_version_number_in_files.py @@ -66,11 +66,6 @@ def update_version_number_in_file(relative_filepath, pattern, new_version_number def bump_version_numbers( new_version_number: VersionNumber, next_version_number: VersionNumber ): - update_version_number_in_file( - "configure.ac", - r"^AC_INIT\(\[BOUT\+\+\],\[(\d+\.\d+\.\d+)\]", - new_version_number, - ) update_version_number_in_file( "CITATION.cff", r"^version: (\d+\.\d+\.\d+)", new_version_number ) diff --git a/build-aux/config.guess b/build-aux/config.guess deleted file mode 100755 index c6fad2f5e5..0000000000 --- a/build-aux/config.guess +++ /dev/null @@ -1,1568 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright 1992-2013 Free Software Foundation, Inc. - -timestamp='2013-06-10' - -# This file 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 to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). -# -# Originally written by Per Bothner. -# -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -# -# Please send patches with a ChangeLog entry to config-patches@gnu.org. - - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright 1992-2013 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -case "${UNAME_SYSTEM}" in -Linux|GNU|GNU/*) - # If the system lacks a compiler, then just pick glibc. - # We could probably try harder. - LIBC=gnu - - eval $set_cc_for_build - cat <<-EOF > $dummy.c - #include - #if defined(__UCLIBC__) - LIBC=uclibc - #elif defined(__dietlibc__) - LIBC=dietlibc - #else - LIBC=gnu - #endif - EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` - ;; -esac - -case "${UNAME_MACHINE}" in - i?86) - test -z "$VENDOR" && VENDOR=pc - ;; - *) - test -z "$VENDOR" && VENDOR=unknown - ;; -esac -test -f /etc/SuSE-release -o -f /.buildenv && VENDOR=suse - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ELF__ - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:Bitrig:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-${VENDOR}-bitrig${UNAME_RELEASE} - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-${VENDOR}-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-${VENDOR}-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Reset EXIT trap before exiting to avoid spurious non-zero exit code. - exitcode=$? - trap '' 0 - exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-${VENDOR}-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-${VENDOR}-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} - exit ;; - i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" - # If there is a compiler, see if it is configured for 64-bit objects. - # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. - # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - SUN_ARCH="x86_64" - fi - fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-${VENDOR}-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[4567]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep -q __LP64__ - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-${VENDOR}-osf1mk - else - echo ${UNAME_MACHINE}-${VENDOR}-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-${VENDOR}-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in - amd64) - echo x86_64-${VENDOR}-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-${VENDOR}-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - authenticamd | genuineintel | EM64T) - echo x86_64-${VENDOR}-interix${UNAME_RELEASE} - exit ;; - IA64) - echo ia64-${VENDOR}-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-${VENDOR}-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-${VENDOR}-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-${VENDOR}-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-${VENDOR}-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-${VENDOR}-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - aarch64_be:Linux:*:*) - UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC}eabi - else - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC}eabihf - fi - fi - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; - crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; - frv:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef ${UNAME_MACHINE} - #undef ${UNAME_MACHINE}el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=${UNAME_MACHINE}el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=${UNAME_MACHINE} - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-${VENDOR}-linux-${LIBC}"; exit; } - ;; - or1k:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - or32:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - padre:Linux:*:*) - echo sparc-${VENDOR}-linux-${LIBC} - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-${VENDOR}-linux-${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-${VENDOR}-linux-${LIBC} ;; - PA8*) echo hppa2.0-${VENDOR}-linux-${LIBC} ;; - *) echo hppa-${VENDOR}-linux-${LIBC} ;; - esac - exit ;; - ppc64:Linux:*:*) - echo powerpc64-${VENDOR}-linux-${LIBC} - exit ;; - ppc:Linux:*:*) - echo powerpc-${VENDOR}-linux-${LIBC} - exit ;; - ppc64le:Linux:*:*) - echo powerpc64le-${VENDOR}-linux-${LIBC} - exit ;; - ppcle:Linux:*:*) - echo powerpcle-${VENDOR}-linux-${LIBC} - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - tile*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} - exit ;; - x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-linux-${LIBC} - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-${VENDOR}-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-${VENODR}-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-${VENDOR}-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i586. - # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that - # this is a cross-build. - echo i586-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-${VENODR}-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - NCR*:*:4.2:* | MPRAS*:*:4.2:*) - OS_REL='.3' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-${VENDOR}-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-${VENDOR}-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-${VENDOR}-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-${VENDOR}-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-${VENDOR}-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; - x86_64:Haiku:*:*) - echo x86_64-${VENDOR}-haiku - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build - if test "$UNAME_PROCESSOR" = unknown ; then - UNAME_PROCESSOR=powerpc - fi - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then - if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null - then - case $UNAME_PROCESSOR in - i386) UNAME_PROCESSOR=x86_64 ;; - powerpc) UNAME_PROCESSOR=powerpc64 ;; - esac - fi - fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; - NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-${VENDOR}-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-${VENDOR}-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-${VENDOR}-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-${VENDOR}-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-${VENDOR}-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; - x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-${VENDOR}-esx - exit ;; -esac - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -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` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/build-aux/config.rpath b/build-aux/config.rpath deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/build-aux/config.sub b/build-aux/config.sub deleted file mode 100755 index 8b612ab89d..0000000000 --- a/build-aux/config.sub +++ /dev/null @@ -1,1788 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright 1992-2013 Free Software Foundation, Inc. - -timestamp='2013-04-24' - -# This file 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 to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that -# program. This Exception is an additional permission under section 7 -# of the GNU General Public License, version 3 ("GPLv3"). - - -# Please send patches with a ChangeLog entry to config-patches@gnu.org. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright 1992-2013 Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ - linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - android-linux) - os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray | -microblaze*) - os= - basic_machine=$1 - ;; - -bluegene*) - os=-cnk - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*178) - os=-lynxos178 - ;; - -lynx*5) - os=-lynxos5 - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arceb \ - | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ - | avr | avr32 \ - | be32 | be64 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | epiphany \ - | fido | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | hexagon \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64octeon | mips64octeonel \ - | mips64orion | mips64orionel \ - | mips64r5900 | mips64r5900el \ - | mips64vr | mips64vrel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ - | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 \ - | or1k | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ - | rl78 | rx \ - | score \ - | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu \ - | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ - | ubicom32 \ - | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ - | we32k \ - | x86 | xc16x | xstormy16 | xtensa \ - | z8k | z80) - basic_machine=$basic_machine-unknown - ;; - c54x) - basic_machine=tic54x-unknown - ;; - c55x) - basic_machine=tic55x-unknown - ;; - c6x) - basic_machine=tic6x-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; - xgate) - basic_machine=$basic_machine-unknown - os=-none - ;; - xscaleeb) - basic_machine=armeb-unknown - ;; - - xscaleel) - basic_machine=armel-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | be32-* | be64-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | le32-* | le64-* \ - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ - | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64octeon-* | mips64octeonel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64r5900-* | mips64r5900el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ - | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ - | pyramid-* \ - | rl78-* | romp-* | rs6000-* | rx-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ - | tahoe-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tile*-* \ - | tron-* \ - | ubicom32-* \ - | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ - | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* \ - | xstormy16-* | xtensa*-* \ - | ymp-* \ - | z8k-* | z80-*) - ;; - # Recognize the basic CPU types without company name, with glob match. - xtensa*) - basic_machine=$basic_machine-unknown - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aros) - basic_machine=i386-pc - os=-aros - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - blackfin) - basic_machine=bfin-unknown - os=-linux - ;; - blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - bluegene*) - basic_machine=powerpc-ibm - os=-cnk - ;; - c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - cegcc) - basic_machine=arm-unknown - os=-cegcc - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16 | cr16-*) - basic_machine=cr16-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dicos) - basic_machine=i686-pc - os=-dicos - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m68knommu) - basic_machine=m68k-unknown - os=-linux - ;; - m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - microblaze*) - basic_machine=microblaze-xilinx - ;; - mingw64) - basic_machine=x86_64-pc - os=-mingw64 - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - mingw32ce) - basic_machine=arm-unknown - os=-mingw32ce - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - msys) - basic_machine=i386-pc - os=-msys - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - nacl) - basic_machine=le32-unknown - os=-nacl - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - neo-tandem) - basic_machine=neo-tandem - ;; - nse-tandem) - basic_machine=nse-tandem - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - parisc) - basic_machine=hppa-unknown - os=-linux - ;; - parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` - os=-linux - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc | ppcbe) basic_machine=powerpc-unknown - ;; - ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos | rdos64) - basic_machine=x86_64-pc - os=-rdos - ;; - rdos32) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tile*) - basic_machine=$basic_machine-unknown - os=-linux-gnu - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -auroraux) - os=-auroraux - ;; - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ - | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ - | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -zvmoe) - os=-zvmoe - ;; - -dicos*) - os=-dicos - ;; - -nacl*) - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - hexagon-*) - os=-elf - ;; - tic54x-*) - os=-coff - ;; - tic55x-*) - os=-coff - ;; - tic6x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - ;; - m68*-cisco) - os=-aout - ;; - mep-*) - os=-elf - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or1k-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -cnk*|-aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/build-aux/install-sh b/build-aux/install-sh deleted file mode 100755 index 377bb8687f..0000000000 --- a/build-aux/install-sh +++ /dev/null @@ -1,527 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2011-11-20.07; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# 'make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -no_target_directory= - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; - - -T) no_target_directory=true;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call 'install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - do_exit='(exit $ret); exit $ret' - trap "ret=129; $do_exit" 1 - trap "ret=130; $do_exit" 2 - trap "ret=141; $do_exit" 13 - trap "ret=143; $do_exit" 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names problematic for 'test' and other utilities. - case $src in - -* | [=\(\)!]) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - dst=$dst_arg - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; - esac - - eval "$initialize_posix_glob" - - oIFS=$IFS - IFS=/ - $posix_glob set -f - set fnord $dstdir - shift - $posix_glob set +f - IFS=$oIFS - - prefixes= - - for d - do - test X"$d" = X && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/build-aux/ltmain.sh b/build-aux/ltmain.sh deleted file mode 100644 index 63ae69dc6f..0000000000 --- a/build-aux/ltmain.sh +++ /dev/null @@ -1,9655 +0,0 @@ - -# libtool (GNU libtool) 2.4.2 -# Written by Gordon Matzigkeit , 1996 - -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, -# 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# GNU Libtool 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 2 of the License, or -# (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, -# or obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# Usage: $progname [OPTION]... [MODE-ARG]... -# -# Provide generalized library-building support services. -# -# --config show all configuration variables -# --debug enable verbose shell tracing -# -n, --dry-run display commands without modifying any files -# --features display basic configuration information and exit -# --mode=MODE use operation mode MODE -# --preserve-dup-deps don't remove duplicate dependency libraries -# --quiet, --silent don't print informational messages -# --no-quiet, --no-silent -# print informational messages (default) -# --no-warn don't display warning messages -# --tag=TAG use configuration variables from tag TAG -# -v, --verbose print more informational messages than default -# --no-verbose don't print the extra informational messages -# --version print version information -# -h, --help, --help-all print short, long, or detailed help message -# -# MODE must be one of the following: -# -# clean remove files from the build directory -# compile compile a source file into a libtool object -# execute automatically set library path, then run a program -# finish complete the installation of libtool libraries -# install install libraries or executables -# link create a library or an executable -# uninstall remove libraries from an installed directory -# -# MODE-ARGS vary depending on the MODE. When passed as first option, -# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. -# Try `$progname --help --mode=MODE' for a more detailed description of MODE. -# -# When reporting a bug, please describe a test case to reproduce it and -# include the following information: -# -# host-triplet: $host -# shell: $SHELL -# compiler: $LTCC -# compiler flags: $LTCFLAGS -# linker: $LD (gnu? $with_gnu_ld) -# $progname: (GNU libtool) 2.4.2 -# automake: $automake_version -# autoconf: $autoconf_version -# -# Report bugs to . -# GNU libtool home page: . -# General help using GNU software: . - -PROGRAM=libtool -PACKAGE=libtool -VERSION=2.4.2 -TIMESTAMP="" -package_revision=1.3337 - -# Be Bourne compatible -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs 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 -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' -} - -# NLS nuisances: We save the old values to restore during execute mode. -lt_user_locale= -lt_safe_locale= -for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES -do - eval "if test \"\${$lt_var+set}\" = set; then - save_$lt_var=\$$lt_var - $lt_var=C - export $lt_var - lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" - lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" - fi" -done -LC_ALL=C -LANGUAGE=C -export LANGUAGE LC_ALL - -$lt_unset CDPATH - - -# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh -# is ksh but when the shell is invoked as "sh" and the current value of -# the _XPG environment variable is not equal to 1 (one), the special -# positional parameter $0, within a function call, is the name of the -# function. -progpath="$0" - - - -: ${CP="cp -f"} -test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} -: ${MAKE="make"} -: ${MKDIR="mkdir"} -: ${MV="mv -f"} -: ${RM="rm -f"} -: ${SHELL="${CONFIG_SHELL-/bin/sh}"} -: ${Xsed="$SED -e 1s/^X//"} - -# Global variables: -EXIT_SUCCESS=0 -EXIT_FAILURE=1 -EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. -EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. - -exit_status=$EXIT_SUCCESS - -# Make sure IFS has a sensible default -lt_nl=' -' -IFS=" $lt_nl" - -dirname="s,/[^/]*$,," -basename="s,^.*/,," - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} # func_dirname may be replaced by extended shell implementation - - -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "${1}" | $SED "$basename"` -} # func_basename may be replaced by extended shell implementation - - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi - func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` -} # func_dirname_and_basename may be replaced by extended shell implementation - - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; - esac -} # func_stripname may be replaced by extended shell implementation - - -# These SED scripts presuppose an absolute path with a trailing slash. -pathcar='s,^/\([^/]*\).*$,\1,' -pathcdr='s,^/[^/]*,,' -removedotparts=':dotsl - s@/\./@/@g - t dotsl - s,/\.$,/,' -collapseslashes='s@/\{1,\}@/@g' -finalslash='s,/*$,/,' - -# func_normal_abspath PATH -# Remove doubled-up and trailing slashes, "." path components, -# and cancel out any ".." path components in PATH after making -# it an absolute path. -# value returned in "$func_normal_abspath_result" -func_normal_abspath () -{ - # Start from root dir and reassemble the path. - func_normal_abspath_result= - func_normal_abspath_tpath=$1 - func_normal_abspath_altnamespace= - case $func_normal_abspath_tpath in - "") - # Empty path, that just means $cwd. - func_stripname '' '/' "`pwd`" - func_normal_abspath_result=$func_stripname_result - return - ;; - # The next three entries are used to spot a run of precisely - # two leading slashes without using negated character classes; - # we take advantage of case's first-match behaviour. - ///*) - # Unusual form of absolute path, do nothing. - ;; - //*) - # Not necessarily an ordinary path; POSIX reserves leading '//' - # and for example Cygwin uses it to access remote file shares - # over CIFS/SMB, so we conserve a leading double slash if found. - func_normal_abspath_altnamespace=/ - ;; - /*) - # Absolute path, do nothing. - ;; - *) - # Relative path, prepend $cwd. - func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath - ;; - esac - # Cancel out all the simple stuff to save iterations. We also want - # the path to end with a slash for ease of parsing, so make sure - # there is one (and only one) here. - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` - while :; do - # Processed it all yet? - if test "$func_normal_abspath_tpath" = / ; then - # If we ascended to the root using ".." the result may be empty now. - if test -z "$func_normal_abspath_result" ; then - func_normal_abspath_result=/ - fi - break - fi - func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcar"` - func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ - -e "$pathcdr"` - # Figure out what to do with it - case $func_normal_abspath_tcomponent in - "") - # Trailing empty path component, ignore it. - ;; - ..) - # Parent dir; strip last assembled component from result. - func_dirname "$func_normal_abspath_result" - func_normal_abspath_result=$func_dirname_result - ;; - *) - # Actual path component, append it. - func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent - ;; - esac - done - # Restore leading double-slash if one was found on entry. - func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result -} - -# func_relative_path SRCDIR DSTDIR -# generates a relative path from SRCDIR to DSTDIR, with a trailing -# slash if non-empty, suitable for immediately appending a filename -# without needing to append a separator. -# value returned in "$func_relative_path_result" -func_relative_path () -{ - func_relative_path_result= - func_normal_abspath "$1" - func_relative_path_tlibdir=$func_normal_abspath_result - func_normal_abspath "$2" - func_relative_path_tbindir=$func_normal_abspath_result - - # Ascend the tree starting from libdir - while :; do - # check if we have found a prefix of bindir - case $func_relative_path_tbindir in - $func_relative_path_tlibdir) - # found an exact match - func_relative_path_tcancelled= - break - ;; - $func_relative_path_tlibdir*) - # found a matching prefix - func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" - func_relative_path_tcancelled=$func_stripname_result - if test -z "$func_relative_path_result"; then - func_relative_path_result=. - fi - break - ;; - *) - func_dirname $func_relative_path_tlibdir - func_relative_path_tlibdir=${func_dirname_result} - if test "x$func_relative_path_tlibdir" = x ; then - # Have to descend all the way to the root! - func_relative_path_result=../$func_relative_path_result - func_relative_path_tcancelled=$func_relative_path_tbindir - break - fi - func_relative_path_result=../$func_relative_path_result - ;; - esac - done - - # Now calculate path; take care to avoid doubling-up slashes. - func_stripname '' '/' "$func_relative_path_result" - func_relative_path_result=$func_stripname_result - func_stripname '/' '/' "$func_relative_path_tcancelled" - if test "x$func_stripname_result" != x ; then - func_relative_path_result=${func_relative_path_result}/${func_stripname_result} - fi - - # Normalisation. If bindir is libdir, return empty string, - # else relative path ending with a slash; either way, target - # file name can be directly appended. - if test ! -z "$func_relative_path_result"; then - func_stripname './' '' "$func_relative_path_result/" - func_relative_path_result=$func_stripname_result - fi -} - -# The name of this program: -func_dirname_and_basename "$progpath" -progname=$func_basename_result - -# Make sure we have an absolute path for reexecution: -case $progpath in - [\\/]*|[A-Za-z]:\\*) ;; - *[\\/]*) - progdir=$func_dirname_result - progdir=`cd "$progdir" && pwd` - progpath="$progdir/$progname" - ;; - *) - save_IFS="$IFS" - IFS=${PATH_SEPARATOR-:} - for progdir in $PATH; do - IFS="$save_IFS" - test -x "$progdir/$progname" && break - done - IFS="$save_IFS" - test -n "$progdir" || progdir=`pwd` - progpath="$progdir/$progname" - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed="${SED}"' -e 1s/^X//' -sed_quote_subst='s/\([`"$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution that turns a string into a regex matching for the -# string literally. -sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' - -# Sed substitution that converts a w32 file name or path -# which contains forward slashes, into one that contains -# (escaped) backslashes. A very naive implementation. -lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' - -# Re-`\' parameter expansions in output of double_quote_subst that were -# `\'-ed in input to the same. If an odd number of `\' preceded a '$' -# in input to double_quote_subst, that '$' was protected from expansion. -# Since each input `\' is now two `\'s, look for any number of runs of -# four `\'s followed by two `\'s and then a '$'. `\' that '$'. -bs='\\' -bs2='\\\\' -bs4='\\\\\\\\' -dollar='\$' -sed_double_backslash="\ - s/$bs4/&\\ -/g - s/^$bs2$dollar/$bs&/ - s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g - s/\n//g" - -# Standard options: -opt_dry_run=false -opt_help=false -opt_quiet=false -opt_verbose=false -opt_warning=: - -# func_echo arg... -# Echo program name prefixed message, along with the current mode -# name if it has been set yet. -func_echo () -{ - $ECHO "$progname: ${opt_mode+$opt_mode: }$*" -} - -# func_verbose arg... -# Echo program name prefixed message in verbose mode only. -func_verbose () -{ - $opt_verbose && func_echo ${1+"$@"} - - # A bug in bash halts the script if the last line of a function - # fails when set -e is in force, so we need another command to - # work around that: - : -} - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "$*" -} - -# func_error arg... -# Echo program name prefixed message to standard error. -func_error () -{ - $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 -} - -# func_warning arg... -# Echo program name prefixed warning message to standard error. -func_warning () -{ - $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 - - # bash bug again: - : -} - -# func_fatal_error arg... -# Echo program name prefixed message to standard error, and exit. -func_fatal_error () -{ - func_error ${1+"$@"} - exit $EXIT_FAILURE -} - -# func_fatal_help arg... -# Echo program name prefixed message to standard error, followed by -# a help hint, and exit. -func_fatal_help () -{ - func_error ${1+"$@"} - func_fatal_error "$help" -} -help="Try \`$progname --help' for more information." ## default - - -# func_grep expression filename -# Check whether EXPRESSION matches any line of FILENAME, without output. -func_grep () -{ - $GREP "$1" "$2" >/dev/null 2>&1 -} - - -# func_mkdir_p directory-path -# Make sure the entire path to DIRECTORY-PATH is available. -func_mkdir_p () -{ - my_directory_path="$1" - my_dir_list= - - if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then - - # Protect directory names starting with `-' - case $my_directory_path in - -*) my_directory_path="./$my_directory_path" ;; - esac - - # While some portion of DIR does not yet exist... - while test ! -d "$my_directory_path"; do - # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. - my_dir_list="$my_directory_path:$my_dir_list" - - # If the last portion added has no slash in it, the list is done - case $my_directory_path in */*) ;; *) break ;; esac - - # ...otherwise throw away the child directory and loop - my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` - done - my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` - - save_mkdir_p_IFS="$IFS"; IFS=':' - for my_dir in $my_dir_list; do - IFS="$save_mkdir_p_IFS" - # mkdir can fail with a `File exist' error if two processes - # try to create one of the directories concurrently. Don't - # stop in that case! - $MKDIR "$my_dir" 2>/dev/null || : - done - IFS="$save_mkdir_p_IFS" - - # Bail out if we (or some other process) failed to create a directory. - test -d "$my_directory_path" || \ - func_fatal_error "Failed to create \`$1'" - fi -} - - -# func_mktempdir [string] -# Make a temporary directory that won't clash with other running -# libtool processes, and avoids race conditions if possible. If -# given, STRING is the basename for that directory. -func_mktempdir () -{ - my_template="${TMPDIR-/tmp}/${1-$progname}" - - if test "$opt_dry_run" = ":"; then - # Return a directory name, but don't create it in dry-run mode - my_tmpdir="${my_template}-$$" - else - - # If mktemp works, use that first and foremost - my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` - - if test ! -d "$my_tmpdir"; then - # Failing that, at least try and use $RANDOM to avoid a race - my_tmpdir="${my_template}-${RANDOM-0}$$" - - save_mktempdir_umask=`umask` - umask 0077 - $MKDIR "$my_tmpdir" - umask $save_mktempdir_umask - fi - - # If we're not in dry-run mode, bomb out on failure - test -d "$my_tmpdir" || \ - func_fatal_error "cannot create temporary directory \`$my_tmpdir'" - fi - - $ECHO "$my_tmpdir" -} - - -# func_quote_for_eval arg -# Aesthetically quote ARG to be evaled later. -# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT -# is double-quoted, suitable for a subsequent eval, whereas -# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters -# which are still active within double quotes backslashified. -func_quote_for_eval () -{ - case $1 in - *[\\\`\"\$]*) - func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; - *) - func_quote_for_eval_unquoted_result="$1" ;; - esac - - case $func_quote_for_eval_unquoted_result in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and and variable - # expansion for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" - ;; - *) - func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" - esac -} - - -# func_quote_for_expand arg -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () -{ - case $1 in - *[\\\`\"]*) - my_arg=`$ECHO "$1" | $SED \ - -e "$double_quote_subst" -e "$sed_double_backslash"` ;; - *) - my_arg="$1" ;; - esac - - case $my_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - my_arg="\"$my_arg\"" - ;; - esac - - func_quote_for_expand_result="$my_arg" -} - - -# func_show_eval cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. -func_show_eval () -{ - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - if ${opt_dry_run-false}; then :; else - eval "$my_cmd" - my_status=$? - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} - - -# func_show_eval_locale cmd [fail_exp] -# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is -# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP -# is given, then evaluate it. Use the saved locale for evaluation. -func_show_eval_locale () -{ - my_cmd="$1" - my_fail_exp="${2-:}" - - ${opt_silent-false} || { - func_quote_for_expand "$my_cmd" - eval "func_echo $func_quote_for_expand_result" - } - - if ${opt_dry_run-false}; then :; else - eval "$lt_user_locale - $my_cmd" - my_status=$? - eval "$lt_safe_locale" - if test "$my_status" -eq 0; then :; else - eval "(exit $my_status); $my_fail_exp" - fi - fi -} - -# func_tr_sh -# Turn $1 into a string suitable for a shell variable name. -# Result is stored in $func_tr_sh_result. All characters -# not in the set a-zA-Z0-9_ are replaced with '_'. Further, -# if $1 begins with a digit, a '_' is prepended as well. -func_tr_sh () -{ - case $1 in - [0-9]* | *[!a-zA-Z0-9_]*) - func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` - ;; - * ) - func_tr_sh_result=$1 - ;; - esac -} - - -# func_version -# Echo version message to standard output and exit. -func_version () -{ - $opt_debug - - $SED -n '/(C)/!b go - :more - /\./!{ - N - s/\n# / / - b more - } - :go - /^# '$PROGRAM' (GNU /,/# warranty; / { - s/^# // - s/^# *$// - s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ - p - }' < "$progpath" - exit $? -} - -# func_usage -# Echo short help message to standard output and exit. -func_usage () -{ - $opt_debug - - $SED -n '/^# Usage:/,/^# *.*--help/ { - s/^# // - s/^# *$// - s/\$progname/'$progname'/ - p - }' < "$progpath" - echo - $ECHO "run \`$progname --help | more' for full usage" - exit $? -} - -# func_help [NOEXIT] -# Echo long help message to standard output and exit, -# unless 'noexit' is passed as argument. -func_help () -{ - $opt_debug - - $SED -n '/^# Usage:/,/# Report bugs to/ { - :print - s/^# // - s/^# *$// - s*\$progname*'$progname'* - s*\$host*'"$host"'* - s*\$SHELL*'"$SHELL"'* - s*\$LTCC*'"$LTCC"'* - s*\$LTCFLAGS*'"$LTCFLAGS"'* - s*\$LD*'"$LD"'* - s/\$with_gnu_ld/'"$with_gnu_ld"'/ - s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ - s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ - p - d - } - /^# .* home page:/b print - /^# General help using/b print - ' < "$progpath" - ret=$? - if test -z "$1"; then - exit $ret - fi -} - -# func_missing_arg argname -# Echo program name prefixed message to standard error and set global -# exit_cmd. -func_missing_arg () -{ - $opt_debug - - func_error "missing argument for $1." - exit_cmd=exit -} - - -# func_split_short_opt shortopt -# Set func_split_short_opt_name and func_split_short_opt_arg shell -# variables after splitting SHORTOPT after the 2nd character. -func_split_short_opt () -{ - my_sed_short_opt='1s/^\(..\).*$/\1/;q' - my_sed_short_rest='1s/^..\(.*\)$/\1/;q' - - func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` - func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` -} # func_split_short_opt may be replaced by extended shell implementation - - -# func_split_long_opt longopt -# Set func_split_long_opt_name and func_split_long_opt_arg shell -# variables after splitting LONGOPT at the `=' sign. -func_split_long_opt () -{ - my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' - my_sed_long_arg='1s/^--[^=]*=//' - - func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` - func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` -} # func_split_long_opt may be replaced by extended shell implementation - -exit_cmd=: - - - - - -magic="%%%MAGIC variable%%%" -magic_exe="%%%MAGIC EXE variable%%%" - -# Global variables. -nonopt= -preserve_args= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" -extracted_archives= -extracted_serial=0 - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "${1}=\$${1}\${2}" -} # func_append may be replaced by extended shell implementation - -# func_append_quoted var value -# Quote VALUE and append to the end of shell variable VAR, separated -# by a space. -func_append_quoted () -{ - func_quote_for_eval "${2}" - eval "${1}=\$${1}\\ \$func_quote_for_eval_result" -} # func_append_quoted may be replaced by extended shell implementation - - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "${@}"` -} # func_arith may be replaced by extended shell implementation - - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` -} # func_len may be replaced by extended shell implementation - - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` -} # func_lo2o may be replaced by extended shell implementation - - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` -} # func_xform may be replaced by extended shell implementation - - -# func_fatal_configuration arg... -# Echo program name prefixed message to standard error, followed by -# a configuration failure hint, and exit. -func_fatal_configuration () -{ - func_error ${1+"$@"} - func_error "See the $PACKAGE documentation for more information." - func_fatal_error "Fatal configuration error." -} - - -# func_config -# Display the configuration for all the tags in this script. -func_config () -{ - re_begincf='^# ### BEGIN LIBTOOL' - re_endcf='^# ### END LIBTOOL' - - # Default configuration. - $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" - - # Now print the configurations for the tags. - for tagname in $taglist; do - $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" - done - - exit $? -} - -# func_features -# Display the features supported by this script. -func_features () -{ - echo "host: $host" - if test "$build_libtool_libs" = yes; then - echo "enable shared libraries" - else - echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - echo "enable static libraries" - else - echo "disable static libraries" - fi - - exit $? -} - -# func_enable_tag tagname -# Verify that TAGNAME is valid, and either flag an error and exit, or -# enable the TAGNAME tag. We also add TAGNAME to the global $taglist -# variable here. -func_enable_tag () -{ - # Global variable: - tagname="$1" - - re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" - re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" - sed_extractcf="/$re_begincf/,/$re_endcf/p" - - # Validate tagname. - case $tagname in - *[!-_A-Za-z0-9,/]*) - func_fatal_error "invalid tag name: $tagname" - ;; - esac - - # Don't test for the "default" C tag, as we know it's - # there but not specially marked. - case $tagname in - CC) ;; - *) - if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then - taglist="$taglist $tagname" - - # Evaluate the configuration. Be careful to quote the path - # and the sed script, to avoid splitting on whitespace, but - # also don't use non-portable quotes within backquotes within - # quotes we have to do it in 2 steps: - extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` - eval "$extractedcf" - else - func_error "ignoring unknown tag $tagname" - fi - ;; - esac -} - -# func_check_version_match -# Ensure that we are using m4 macros, and libtool script from the same -# release of libtool. -func_check_version_match () -{ - if test "$package_revision" != "$macro_revision"; then - if test "$VERSION" != "$macro_version"; then - if test -z "$macro_version"; then - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from an older release. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, but the -$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. -$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION -$progname: and run autoconf again. -_LT_EOF - fi - else - cat >&2 <<_LT_EOF -$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, -$progname: but the definition of this LT_INIT comes from revision $macro_revision. -$progname: You should recreate aclocal.m4 with macros from revision $package_revision -$progname: of $PACKAGE $VERSION and run autoconf again. -_LT_EOF - fi - - exit $EXIT_MISMATCH - fi -} - - -# Shorthand for --mode=foo, only valid as the first argument -case $1 in -clean|clea|cle|cl) - shift; set dummy --mode clean ${1+"$@"}; shift - ;; -compile|compil|compi|comp|com|co|c) - shift; set dummy --mode compile ${1+"$@"}; shift - ;; -execute|execut|execu|exec|exe|ex|e) - shift; set dummy --mode execute ${1+"$@"}; shift - ;; -finish|finis|fini|fin|fi|f) - shift; set dummy --mode finish ${1+"$@"}; shift - ;; -install|instal|insta|inst|ins|in|i) - shift; set dummy --mode install ${1+"$@"}; shift - ;; -link|lin|li|l) - shift; set dummy --mode link ${1+"$@"}; shift - ;; -uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) - shift; set dummy --mode uninstall ${1+"$@"}; shift - ;; -esac - - - -# Option defaults: -opt_debug=: -opt_dry_run=false -opt_config=false -opt_preserve_dup_deps=false -opt_features=false -opt_finish=false -opt_help=false -opt_help_all=false -opt_silent=: -opt_warning=: -opt_verbose=: -opt_silent=false -opt_verbose=false - - -# Parse options once, thoroughly. This comes as soon as possible in the -# script to make things like `--version' happen as quickly as we can. -{ - # this just eases exit handling - while test $# -gt 0; do - opt="$1" - shift - case $opt in - --debug|-x) opt_debug='set -x' - func_echo "enabling shell trace mode" - $opt_debug - ;; - --dry-run|--dryrun|-n) - opt_dry_run=: - ;; - --config) - opt_config=: -func_config - ;; - --dlopen|-dlopen) - optarg="$1" - opt_dlopen="${opt_dlopen+$opt_dlopen -}$optarg" - shift - ;; - --preserve-dup-deps) - opt_preserve_dup_deps=: - ;; - --features) - opt_features=: -func_features - ;; - --finish) - opt_finish=: -set dummy --mode finish ${1+"$@"}; shift - ;; - --help) - opt_help=: - ;; - --help-all) - opt_help_all=: -opt_help=': help-all' - ;; - --mode) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_mode="$optarg" -case $optarg in - # Valid mode arguments: - clean|compile|execute|finish|install|link|relink|uninstall) ;; - - # Catch anything else as an error - *) func_error "invalid argument for $opt" - exit_cmd=exit - break - ;; -esac - shift - ;; - --no-silent|--no-quiet) - opt_silent=false -func_append preserve_args " $opt" - ;; - --no-warning|--no-warn) - opt_warning=false -func_append preserve_args " $opt" - ;; - --no-verbose) - opt_verbose=false -func_append preserve_args " $opt" - ;; - --silent|--quiet) - opt_silent=: -func_append preserve_args " $opt" - opt_verbose=false - ;; - --verbose|-v) - opt_verbose=: -func_append preserve_args " $opt" -opt_silent=false - ;; - --tag) - test $# = 0 && func_missing_arg $opt && break - optarg="$1" - opt_tag="$optarg" -func_append preserve_args " $opt $optarg" -func_enable_tag "$optarg" - shift - ;; - - -\?|-h) func_usage ;; - --help) func_help ;; - --version) func_version ;; - - # Separate optargs to long options: - --*=*) - func_split_long_opt "$opt" - set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} - shift - ;; - - # Separate non-argument short options: - -\?*|-h*|-n*|-v*) - func_split_short_opt "$opt" - set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} - shift - ;; - - --) break ;; - -*) func_fatal_help "unrecognized option \`$opt'" ;; - *) set dummy "$opt" ${1+"$@"}; shift; break ;; - esac - done - - # Validate options: - - # save first non-option argument - if test "$#" -gt 0; then - nonopt="$opt" - shift - fi - - # preserve --debug - test "$opt_debug" = : || func_append preserve_args " --debug" - - case $host in - *cygwin* | *mingw* | *pw32* | *cegcc*) - # don't eliminate duplications in $postdeps and $predeps - opt_duplicate_compiler_generated_deps=: - ;; - *) - opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps - ;; - esac - - $opt_help || { - # Sanity checks first: - func_check_version_match - - if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then - func_fatal_configuration "not configured to build any kind of library" - fi - - # Darwin sucks - eval std_shrext=\"$shrext_cmds\" - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$opt_dlopen" && test "$opt_mode" != execute; then - func_error "unrecognized option \`-dlopen'" - $ECHO "$help" 1>&2 - exit $EXIT_FAILURE - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$progname --help --mode=$opt_mode' for more information." - } - - - # Bail if the options were screwed - $exit_cmd $EXIT_FAILURE -} - - - - -## ----------- ## -## Main. ## -## ----------- ## - -# func_lalib_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_lalib_p () -{ - test -f "$1" && - $SED -e 4q "$1" 2>/dev/null \ - | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 -} - -# func_lalib_unsafe_p file -# True iff FILE is a libtool `.la' library or `.lo' object file. -# This function implements the same check as func_lalib_p without -# resorting to external programs. To this end, it redirects stdin and -# closes it afterwards, without saving the original file descriptor. -# As a safety measure, use it only where a negative result would be -# fatal anyway. Works if `file' does not exist. -func_lalib_unsafe_p () -{ - lalib_p=no - if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then - for lalib_p_l in 1 2 3 4 - do - read lalib_p_line - case "$lalib_p_line" in - \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; - esac - done - exec 0<&5 5<&- - fi - test "$lalib_p" = yes -} - -# func_ltwrapper_script_p file -# True iff FILE is a libtool wrapper script -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_script_p () -{ - func_lalib_p "$1" -} - -# func_ltwrapper_executable_p file -# True iff FILE is a libtool wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_executable_p () -{ - func_ltwrapper_exec_suffix= - case $1 in - *.exe) ;; - *) func_ltwrapper_exec_suffix=.exe ;; - esac - $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 -} - -# func_ltwrapper_scriptname file -# Assumes file is an ltwrapper_executable -# uses $file to determine the appropriate filename for a -# temporary ltwrapper_script. -func_ltwrapper_scriptname () -{ - func_dirname_and_basename "$1" "" "." - func_stripname '' '.exe' "$func_basename_result" - func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" -} - -# func_ltwrapper_p file -# True iff FILE is a libtool wrapper script or wrapper executable -# This function is only a basic sanity check; it will hardly flush out -# determined imposters. -func_ltwrapper_p () -{ - func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" -} - - -# func_execute_cmds commands fail_cmd -# Execute tilde-delimited COMMANDS. -# If FAIL_CMD is given, eval that upon failure. -# FAIL_CMD may read-access the current command in variable CMD! -func_execute_cmds () -{ - $opt_debug - save_ifs=$IFS; IFS='~' - for cmd in $1; do - IFS=$save_ifs - eval cmd=\"$cmd\" - func_show_eval "$cmd" "${2-:}" - done - IFS=$save_ifs -} - - -# func_source file -# Source FILE, adding directory component if necessary. -# Note that it is not necessary on cygwin/mingw to append a dot to -# FILE even if both FILE and FILE.exe exist: automatic-append-.exe -# behavior happens only for exec(3), not for open(2)! Also, sourcing -# `FILE.' does not work on cygwin managed mounts. -func_source () -{ - $opt_debug - case $1 in - */* | *\\*) . "$1" ;; - *) . "./$1" ;; - esac -} - - -# func_resolve_sysroot PATH -# Replace a leading = in PATH with a sysroot. Store the result into -# func_resolve_sysroot_result -func_resolve_sysroot () -{ - func_resolve_sysroot_result=$1 - case $func_resolve_sysroot_result in - =*) - func_stripname '=' '' "$func_resolve_sysroot_result" - func_resolve_sysroot_result=$lt_sysroot$func_stripname_result - ;; - esac -} - -# func_replace_sysroot PATH -# If PATH begins with the sysroot, replace it with = and -# store the result into func_replace_sysroot_result. -func_replace_sysroot () -{ - case "$lt_sysroot:$1" in - ?*:"$lt_sysroot"*) - func_stripname "$lt_sysroot" '' "$1" - func_replace_sysroot_result="=$func_stripname_result" - ;; - *) - # Including no sysroot. - func_replace_sysroot_result=$1 - ;; - esac -} - -# func_infer_tag arg -# Infer tagged configuration to use if any are available and -# if one wasn't chosen via the "--tag" command line option. -# Only attempt this if the compiler in the base compile -# command doesn't match the default compiler. -# arg is usually of the form 'gcc ...' -func_infer_tag () -{ - $opt_debug - if test -n "$available_tags" && test -z "$tagname"; then - CC_quoted= - for arg in $CC; do - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case $@ in - # Blanks in the command may have been stripped by the calling shell, - # but not from the CC environment variable when configure was run. - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; - # Blanks at the start of $base_compile will cause this to fail - # if we don't check for them as well. - *) - for z in $available_tags; do - if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then - # Evaluate the configuration. - eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" - CC_quoted= - for arg in $CC; do - # Double-quote args containing other shell metacharacters. - func_append_quoted CC_quoted "$arg" - done - CC_expanded=`func_echo_all $CC` - CC_quoted_expanded=`func_echo_all $CC_quoted` - case "$@ " in - " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ - " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) - # The compiler in the base compile command matches - # the one in the tagged configuration. - # Assume this is the tagged configuration we want. - tagname=$z - break - ;; - esac - fi - done - # If $tagname still isn't set, then no tagged configuration - # was found and let the user know that the "--tag" command - # line option must be used. - if test -z "$tagname"; then - func_echo "unable to infer tagged configuration" - func_fatal_error "specify a tag with \`--tag'" -# else -# func_verbose "using $tagname tagged configuration" - fi - ;; - esac - fi -} - - - -# func_write_libtool_object output_name pic_name nonpic_name -# Create a libtool object file (analogous to a ".la" file), -# but don't create it if we're doing a dry run. -func_write_libtool_object () -{ - write_libobj=${1} - if test "$build_libtool_libs" = yes; then - write_lobj=\'${2}\' - else - write_lobj=none - fi - - if test "$build_old_libs" = yes; then - write_oldobj=\'${3}\' - else - write_oldobj=none - fi - - $opt_dry_run || { - cat >${write_libobj}T </dev/null` - if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then - func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | - $SED -e "$lt_sed_naive_backslashify"` - else - func_convert_core_file_wine_to_w32_result= - fi - fi -} -# end: func_convert_core_file_wine_to_w32 - - -# func_convert_core_path_wine_to_w32 ARG -# Helper function used by path conversion functions when $build is *nix, and -# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly -# configured wine environment available, with the winepath program in $build's -# $PATH. Assumes ARG has no leading or trailing path separator characters. -# -# ARG is path to be converted from $build format to win32. -# Result is available in $func_convert_core_path_wine_to_w32_result. -# Unconvertible file (directory) names in ARG are skipped; if no directory names -# are convertible, then the result may be empty. -func_convert_core_path_wine_to_w32 () -{ - $opt_debug - # unfortunately, winepath doesn't convert paths, only file names - func_convert_core_path_wine_to_w32_result="" - if test -n "$1"; then - oldIFS=$IFS - IFS=: - for func_convert_core_path_wine_to_w32_f in $1; do - IFS=$oldIFS - func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" - if test -n "$func_convert_core_file_wine_to_w32_result" ; then - if test -z "$func_convert_core_path_wine_to_w32_result"; then - func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" - else - func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" - fi - fi - done - IFS=$oldIFS - fi -} -# end: func_convert_core_path_wine_to_w32 - - -# func_cygpath ARGS... -# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when -# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) -# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or -# (2), returns the Cygwin file name or path in func_cygpath_result (input -# file name or path is assumed to be in w32 format, as previously converted -# from $build's *nix or MSYS format). In case (3), returns the w32 file name -# or path in func_cygpath_result (input file name or path is assumed to be in -# Cygwin format). Returns an empty string on error. -# -# ARGS are passed to cygpath, with the last one being the file name or path to -# be converted. -# -# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH -# environment variable; do not put it in $PATH. -func_cygpath () -{ - $opt_debug - if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then - func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` - if test "$?" -ne 0; then - # on failure, ensure result is empty - func_cygpath_result= - fi - else - func_cygpath_result= - func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" - fi -} -#end: func_cygpath - - -# func_convert_core_msys_to_w32 ARG -# Convert file name or path ARG from MSYS format to w32 format. Return -# result in func_convert_core_msys_to_w32_result. -func_convert_core_msys_to_w32 () -{ - $opt_debug - # awkward: cmd appends spaces to result - func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | - $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` -} -#end: func_convert_core_msys_to_w32 - - -# func_convert_file_check ARG1 ARG2 -# Verify that ARG1 (a file name in $build format) was converted to $host -# format in ARG2. Otherwise, emit an error message, but continue (resetting -# func_to_host_file_result to ARG1). -func_convert_file_check () -{ - $opt_debug - if test -z "$2" && test -n "$1" ; then - func_error "Could not determine host file name corresponding to" - func_error " \`$1'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback: - func_to_host_file_result="$1" - fi -} -# end func_convert_file_check - - -# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH -# Verify that FROM_PATH (a path in $build format) was converted to $host -# format in TO_PATH. Otherwise, emit an error message, but continue, resetting -# func_to_host_file_result to a simplistic fallback value (see below). -func_convert_path_check () -{ - $opt_debug - if test -z "$4" && test -n "$3"; then - func_error "Could not determine the host path corresponding to" - func_error " \`$3'" - func_error "Continuing, but uninstalled executables may not work." - # Fallback. This is a deliberately simplistic "conversion" and - # should not be "improved". See libtool.info. - if test "x$1" != "x$2"; then - lt_replace_pathsep_chars="s|$1|$2|g" - func_to_host_path_result=`echo "$3" | - $SED -e "$lt_replace_pathsep_chars"` - else - func_to_host_path_result="$3" - fi - fi -} -# end func_convert_path_check - - -# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG -# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT -# and appending REPL if ORIG matches BACKPAT. -func_convert_path_front_back_pathsep () -{ - $opt_debug - case $4 in - $1 ) func_to_host_path_result="$3$func_to_host_path_result" - ;; - esac - case $4 in - $2 ) func_append func_to_host_path_result "$3" - ;; - esac -} -# end func_convert_path_front_back_pathsep - - -################################################## -# $build to $host FILE NAME CONVERSION FUNCTIONS # -################################################## -# invoked via `$to_host_file_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# Result will be available in $func_to_host_file_result. - - -# func_to_host_file ARG -# Converts the file name ARG from $build format to $host format. Return result -# in func_to_host_file_result. -func_to_host_file () -{ - $opt_debug - $to_host_file_cmd "$1" -} -# end func_to_host_file - - -# func_to_tool_file ARG LAZY -# converts the file name ARG from $build format to toolchain format. Return -# result in func_to_tool_file_result. If the conversion in use is listed -# in (the comma separated) LAZY, no conversion takes place. -func_to_tool_file () -{ - $opt_debug - case ,$2, in - *,"$to_tool_file_cmd",*) - func_to_tool_file_result=$1 - ;; - *) - $to_tool_file_cmd "$1" - func_to_tool_file_result=$func_to_host_file_result - ;; - esac -} -# end func_to_tool_file - - -# func_convert_file_noop ARG -# Copy ARG to func_to_host_file_result. -func_convert_file_noop () -{ - func_to_host_file_result="$1" -} -# end func_convert_file_noop - - -# func_convert_file_msys_to_w32 ARG -# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_file_result. -func_convert_file_msys_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_to_host_file_result="$func_convert_core_msys_to_w32_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_w32 - - -# func_convert_file_cygwin_to_w32 ARG -# Convert file name ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_file_cygwin_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - # because $build is cygwin, we call "the" cygpath in $PATH; no need to use - # LT_CYGPATH in this case. - func_to_host_file_result=`cygpath -m "$1"` - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_cygwin_to_w32 - - -# func_convert_file_nix_to_w32 ARG -# Convert file name ARG from *nix to w32 format. Requires a wine environment -# and a working winepath. Returns result in func_to_host_file_result. -func_convert_file_nix_to_w32 () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_file_wine_to_w32 "$1" - func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_w32 - - -# func_convert_file_msys_to_cygwin ARG -# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_file_msys_to_cygwin () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - func_convert_core_msys_to_w32 "$1" - func_cygpath -u "$func_convert_core_msys_to_w32_result" - func_to_host_file_result="$func_cygpath_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_msys_to_cygwin - - -# func_convert_file_nix_to_cygwin ARG -# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed -# in a wine environment, working winepath, and LT_CYGPATH set. Returns result -# in func_to_host_file_result. -func_convert_file_nix_to_cygwin () -{ - $opt_debug - func_to_host_file_result="$1" - if test -n "$1"; then - # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. - func_convert_core_file_wine_to_w32 "$1" - func_cygpath -u "$func_convert_core_file_wine_to_w32_result" - func_to_host_file_result="$func_cygpath_result" - fi - func_convert_file_check "$1" "$func_to_host_file_result" -} -# end func_convert_file_nix_to_cygwin - - -############################################# -# $build to $host PATH CONVERSION FUNCTIONS # -############################################# -# invoked via `$to_host_path_cmd ARG' -# -# In each case, ARG is the path to be converted from $build to $host format. -# The result will be available in $func_to_host_path_result. -# -# Path separators are also converted from $build format to $host format. If -# ARG begins or ends with a path separator character, it is preserved (but -# converted to $host format) on output. -# -# All path conversion functions are named using the following convention: -# file name conversion function : func_convert_file_X_to_Y () -# path conversion function : func_convert_path_X_to_Y () -# where, for any given $build/$host combination the 'X_to_Y' value is the -# same. If conversion functions are added for new $build/$host combinations, -# the two new functions must follow this pattern, or func_init_to_host_path_cmd -# will break. - - -# func_init_to_host_path_cmd -# Ensures that function "pointer" variable $to_host_path_cmd is set to the -# appropriate value, based on the value of $to_host_file_cmd. -to_host_path_cmd= -func_init_to_host_path_cmd () -{ - $opt_debug - if test -z "$to_host_path_cmd"; then - func_stripname 'func_convert_file_' '' "$to_host_file_cmd" - to_host_path_cmd="func_convert_path_${func_stripname_result}" - fi -} - - -# func_to_host_path ARG -# Converts the path ARG from $build format to $host format. Return result -# in func_to_host_path_result. -func_to_host_path () -{ - $opt_debug - func_init_to_host_path_cmd - $to_host_path_cmd "$1" -} -# end func_to_host_path - - -# func_convert_path_noop ARG -# Copy ARG to func_to_host_path_result. -func_convert_path_noop () -{ - func_to_host_path_result="$1" -} -# end func_convert_path_noop - - -# func_convert_path_msys_to_w32 ARG -# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic -# conversion to w32 is not available inside the cwrapper. Returns result in -# func_to_host_path_result. -func_convert_path_msys_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # Remove leading and trailing path separator characters from ARG. MSYS - # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; - # and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_msys_to_w32_result" - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_msys_to_w32 - - -# func_convert_path_cygwin_to_w32 ARG -# Convert path ARG from Cygwin to w32 format. Returns result in -# func_to_host_file_result. -func_convert_path_cygwin_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_cygwin_to_w32 - - -# func_convert_path_nix_to_w32 ARG -# Convert path ARG from *nix to w32 format. Requires a wine environment and -# a working winepath. Returns result in func_to_host_file_result. -func_convert_path_nix_to_w32 () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" - func_convert_path_check : ";" \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" - fi -} -# end func_convert_path_nix_to_w32 - - -# func_convert_path_msys_to_cygwin ARG -# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. -# Returns result in func_to_host_file_result. -func_convert_path_msys_to_cygwin () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # See func_convert_path_msys_to_w32: - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_msys_to_w32_result" - func_to_host_path_result="$func_cygpath_result" - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_msys_to_cygwin - - -# func_convert_path_nix_to_cygwin ARG -# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a -# a wine environment, working winepath, and LT_CYGPATH set. Returns result in -# func_to_host_file_result. -func_convert_path_nix_to_cygwin () -{ - $opt_debug - func_to_host_path_result="$1" - if test -n "$1"; then - # Remove leading and trailing path separator characters from - # ARG. msys behavior is inconsistent here, cygpath turns them - # into '.;' and ';.', and winepath ignores them completely. - func_stripname : : "$1" - func_to_host_path_tmp1=$func_stripname_result - func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" - func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" - func_to_host_path_result="$func_cygpath_result" - func_convert_path_check : : \ - "$func_to_host_path_tmp1" "$func_to_host_path_result" - func_convert_path_front_back_pathsep ":*" "*:" : "$1" - fi -} -# end func_convert_path_nix_to_cygwin - - -# func_mode_compile arg... -func_mode_compile () -{ - $opt_debug - # Get the compilation command and the source file. - base_compile= - srcfile="$nonopt" # always keep a non-empty value in "srcfile" - suppress_opt=yes - suppress_output= - arg_mode=normal - libobj= - later= - pie_flag= - - for arg - do - case $arg_mode in - arg ) - # do not "continue". Instead, add this to base_compile - lastarg="$arg" - arg_mode=normal - ;; - - target ) - libobj="$arg" - arg_mode=normal - continue - ;; - - normal ) - # Accept any command-line options. - case $arg in - -o) - test -n "$libobj" && \ - func_fatal_error "you cannot specify \`-o' more than once" - arg_mode=target - continue - ;; - - -pie | -fpie | -fPIE) - func_append pie_flag " $arg" - continue - ;; - - -shared | -static | -prefer-pic | -prefer-non-pic) - func_append later " $arg" - continue - ;; - - -no-suppress) - suppress_opt=no - continue - ;; - - -Xcompiler) - arg_mode=arg # the next one goes into the "base_compile" arg list - continue # The current "srcfile" will either be retained or - ;; # replaced later. I would guess that would be a bug. - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - lastarg= - save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - func_append_quoted lastarg "$arg" - done - IFS="$save_ifs" - func_stripname ' ' '' "$lastarg" - lastarg=$func_stripname_result - - # Add the arguments to base_compile. - func_append base_compile " $lastarg" - continue - ;; - - *) - # Accept the current argument as the source file. - # The previous "srcfile" becomes the current argument. - # - lastarg="$srcfile" - srcfile="$arg" - ;; - esac # case $arg - ;; - esac # case $arg_mode - - # Aesthetically quote the previous argument. - func_append_quoted base_compile "$lastarg" - done # for arg - - case $arg_mode in - arg) - func_fatal_error "you must specify an argument for -Xcompile" - ;; - target) - func_fatal_error "you must specify a target with \`-o'" - ;; - *) - # Get the name of the library object. - test -z "$libobj" && { - func_basename "$srcfile" - libobj="$func_basename_result" - } - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - case $libobj in - *.[cCFSifmso] | \ - *.ada | *.adb | *.ads | *.asm | \ - *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ - *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) - func_xform "$libobj" - libobj=$func_xform_result - ;; - esac - - case $libobj in - *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; - *) - func_fatal_error "cannot determine name of library object from \`$libobj'" - ;; - esac - - func_infer_tag $base_compile - - for arg in $later; do - case $arg in - -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" - build_old_libs=no - continue - ;; - - -static) - build_libtool_libs=no - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - esac - done - - func_quote_for_eval "$libobj" - test "X$libobj" != "X$func_quote_for_eval_result" \ - && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ - && func_warning "libobj name \`$libobj' may not contain shell special characters." - func_dirname_and_basename "$obj" "/" "" - objname="$func_basename_result" - xdir="$func_dirname_result" - lobj=${xdir}$objdir/$objname - - test -z "$base_compile" && \ - func_fatal_help "you must specify a compilation command" - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $lobj $libobj ${libobj}T" - else - removelist="$lobj $libobj ${libobj}T" - fi - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2* | cegcc*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - else - output_obj= - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - $ECHO "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - func_append removelist " $output_obj" - $ECHO "$srcfile" > "$lockfile" - fi - - $opt_dry_run || $RM $removelist - func_append removelist " $lockfile" - trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 - - func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 - srcfile=$func_to_tool_file_result - func_quote_for_eval "$srcfile" - qsrcfile=$func_quote_for_eval_result - - # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test "$pic_mode" != no; then - command="$base_compile $qsrcfile $pic_flag" - else - # Don't build PIC code - command="$base_compile $qsrcfile" - fi - - func_mkdir_p "$xdir$objdir" - - if test -z "$output_obj"; then - # Place PIC objects in $objdir - func_append command " -o $lobj" - fi - - func_show_eval_locale "$command" \ - 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed, then go on to compile the next one - if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then - func_show_eval '$MV "$output_obj" "$lobj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - - # Allow error messages only from the first compilation. - if test "$suppress_opt" = yes; then - suppress_output=' >/dev/null 2>&1' - fi - fi - - # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then - # Don't build PIC code - command="$base_compile $qsrcfile$pie_flag" - else - command="$base_compile $qsrcfile $pic_flag" - fi - if test "$compiler_c_o" = yes; then - func_append command " -o $obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - func_append command "$suppress_output" - func_show_eval_locale "$command" \ - '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' - - if test "$need_locks" = warn && - test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then - $ECHO "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $opt_dry_run || $RM $removelist - exit $EXIT_FAILURE - fi - - # Just move the object if needed - if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then - func_show_eval '$MV "$output_obj" "$obj"' \ - 'error=$?; $opt_dry_run || $RM $removelist; exit $error' - fi - fi - - $opt_dry_run || { - func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" - - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - removelist=$lockfile - $RM "$lockfile" - fi - } - - exit $EXIT_SUCCESS -} - -$opt_help || { - test "$opt_mode" = compile && func_mode_compile ${1+"$@"} -} - -func_mode_help () -{ - # We need to display help for each of the modes. - case $opt_mode in - "") - # Generic help is extracted from the usage comments - # at the start of this file. - func_help - ;; - - clean) - $ECHO \ -"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - - compile) - $ECHO \ -"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -no-suppress do not suppress compiler output for multiple passes - -prefer-pic try to build PIC objects only - -prefer-non-pic try to build non-PIC objects only - -shared do not build a \`.o' file suitable for static linking - -static only build a \`.o' file suitable for static linking - -Wc,FLAG pass FLAG directly to the compiler - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - - execute) - $ECHO \ -"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - - finish) - $ECHO \ -"Usage: $progname [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - - install) - $ECHO \ -"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The following components of INSTALL-COMMAND are treated specially: - - -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - - link) - $ECHO \ -"Usage: $progname [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -bindir BINDIR specify path to binaries directory (for systems where - libraries must be found in the PATH setting at runtime) - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -objectlist FILE Use a list of object files found in FILE to specify objects - -precious-files-regex REGEX - don't remove output files matching REGEX - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -shared only do dynamic linking of libtool libraries - -shrext SUFFIX override the standard shared library file extension - -static do not do any dynamic linking of uninstalled libtool libraries - -static-libtool-libs - do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -weak LIBNAME declare that the target provides the LIBNAME interface - -Wc,FLAG - -Xcompiler FLAG pass linker-specific FLAG directly to the compiler - -Wl,FLAG - -Xlinker FLAG pass linker-specific FLAG directly to the linker - -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - - uninstall) - $ECHO \ -"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - - *) - func_fatal_help "invalid operation mode \`$opt_mode'" - ;; - esac - - echo - $ECHO "Try \`$progname --help' for more information about other modes." -} - -# Now that we've collected a possible --mode arg, show help if necessary -if $opt_help; then - if test "$opt_help" = :; then - func_mode_help - else - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - func_mode_help - done - } | sed -n '1p; 2,$s/^Usage:/ or: /p' - { - func_help noexit - for opt_mode in compile link execute install finish uninstall clean; do - echo - func_mode_help - done - } | - sed '1d - /^When reporting/,/^Report/{ - H - d - } - $x - /information about other modes/d - /more detailed .*MODE/d - s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' - fi - exit $? -fi - - -# func_mode_execute arg... -func_mode_execute () -{ - $opt_debug - # The first argument is the command name. - cmd="$nonopt" - test -z "$cmd" && \ - func_fatal_help "you must specify a COMMAND" - - # Handle -dlopen flags immediately. - for file in $opt_dlopen; do - test -f "$file" \ - || func_fatal_help "\`$file' is not a file" - - dir= - case $file in - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$lib' is not a valid libtool archive" - - # Read the libtool library. - dlname= - library_names= - func_source "$file" - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && \ - func_warning "\`$file' was not linked with \`-export-dynamic'" - continue - fi - - func_dirname "$file" "" "." - dir="$func_dirname_result" - - if test -f "$dir/$objdir/$dlname"; then - func_append dir "/$objdir" - else - if test ! -f "$dir/$dlname"; then - func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" - fi - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - func_dirname "$file" "" "." - dir="$func_dirname_result" - ;; - - *) - func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -* | *.la | *.lo ) ;; - *) - # Do a test to see if this is really a libtool program. - if func_ltwrapper_script_p "$file"; then - func_source "$file" - # Transform arg to wrapped name. - file="$progdir/$program" - elif func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - func_source "$func_ltwrapper_scriptname_result" - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - func_append_quoted args "$file" - done - - if test "X$opt_dry_run" = Xfalse; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved environment variables - for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES - do - eval "if test \"\${save_$lt_var+set}\" = set; then - $lt_var=\$save_$lt_var; export $lt_var - else - $lt_unset $lt_var - fi" - done - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" - echo "export $shlibpath_var" - fi - $ECHO "$cmd$args" - exit $EXIT_SUCCESS - fi -} - -test "$opt_mode" = execute && func_mode_execute ${1+"$@"} - - -# func_mode_finish arg... -func_mode_finish () -{ - $opt_debug - libs= - libdirs= - admincmds= - - for opt in "$nonopt" ${1+"$@"} - do - if test -d "$opt"; then - func_append libdirs " $opt" - - elif test -f "$opt"; then - if func_lalib_unsafe_p "$opt"; then - func_append libs " $opt" - else - func_warning "\`$opt' is not a valid libtool archive" - fi - - else - func_fatal_error "invalid argument \`$opt'" - fi - done - - if test -n "$libs"; then - if test -n "$lt_sysroot"; then - sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` - sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" - else - sysroot_cmd= - fi - - # Remove sysroot references - if $opt_dry_run; then - for lib in $libs; do - echo "removing references to $lt_sysroot and \`=' prefixes from $lib" - done - else - tmpdir=`func_mktempdir` - for lib in $libs; do - sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ - > $tmpdir/tmp-la - mv -f $tmpdir/tmp-la $lib - done - ${RM}r "$tmpdir" - fi - fi - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - func_execute_cmds "$finish_cmds" 'admincmds="$admincmds -'"$cmd"'"' - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $opt_dry_run || eval "$cmds" || func_append admincmds " - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - $opt_silent && exit $EXIT_SUCCESS - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - echo "----------------------------------------------------------------------" - echo "Libraries have been installed in:" - for libdir in $libdirs; do - $ECHO " $libdir" - done - echo - echo "If you ever happen to want to link against installed libraries" - echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - echo " during execution" - fi - if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" - echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - $ECHO " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - $ECHO " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - echo - - echo "See any operating system documentation about shared libraries for" - case $host in - solaris2.[6789]|solaris2.1[0-9]) - echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" - echo "pages." - ;; - *) - echo "more information, such as the ld(1) and ld.so(8) manual pages." - ;; - esac - echo "----------------------------------------------------------------------" - fi - exit $EXIT_SUCCESS -} - -test "$opt_mode" = finish && func_mode_finish ${1+"$@"} - - -# func_mode_install arg... -func_mode_install () -{ - $opt_debug - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - case $nonopt in *shtool*) :;; *) false;; esac; then - # Aesthetically quote it. - func_quote_for_eval "$nonopt" - install_prog="$func_quote_for_eval_result " - arg=$1 - shift - else - install_prog= - arg=$nonopt - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - func_quote_for_eval "$arg" - func_append install_prog "$func_quote_for_eval_result" - install_shared_prog=$install_prog - case " $install_prog " in - *[\\\ /]cp\ *) install_cp=: ;; - *) install_cp=false ;; - esac - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - no_mode=: - for arg - do - arg2= - if test -n "$dest"; then - func_append files " $dest" - dest=$arg - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) - if $install_cp; then :; else - prev=$arg - fi - ;; - -g | -m | -o) - prev=$arg - ;; - -s) - stripme=" -s" - continue - ;; - -*) - ;; - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - if test "x$prev" = x-m && test -n "$install_override_mode"; then - arg2=$install_override_mode - no_mode=false - fi - prev= - else - dest=$arg - continue - fi - ;; - esac - - # Aesthetically quote the argument. - func_quote_for_eval "$arg" - func_append install_prog " $func_quote_for_eval_result" - if test -n "$arg2"; then - func_quote_for_eval "$arg2" - fi - func_append install_shared_prog " $func_quote_for_eval_result" - done - - test -z "$install_prog" && \ - func_fatal_help "you must specify an install program" - - test -n "$prev" && \ - func_fatal_help "the \`$prev' option requires an argument" - - if test -n "$install_override_mode" && $no_mode; then - if $install_cp; then :; else - func_quote_for_eval "$install_override_mode" - func_append install_shared_prog " -m $func_quote_for_eval_result" - fi - fi - - if test -z "$files"; then - if test -z "$dest"; then - func_fatal_help "no file or destination specified" - else - func_fatal_help "you must specify a destination" - fi - fi - - # Strip any trailing slash from the destination. - func_stripname '' '/' "$dest" - dest=$func_stripname_result - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - func_dirname_and_basename "$dest" "" "." - destdir="$func_dirname_result" - destname="$func_basename_result" - - # Not a directory, so check to see that there is only one file specified. - set dummy $files; shift - test "$#" -gt 1 && \ - func_fatal_help "\`$dest' is not a directory" - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - func_fatal_help "\`$destdir' must be an absolute directory name" - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - func_append staticlibs " $file" - ;; - - *.la) - func_resolve_sysroot "$file" - file=$func_resolve_sysroot_result - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$file" \ - || func_fatal_help "\`$file' is not a valid libtool archive" - - library_names= - old_library= - relink_command= - func_source "$file" - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) func_append current_libdirs " $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) func_append future_libdirs " $libdir" ;; - esac - fi - - func_dirname "$file" "/" "" - dir="$func_dirname_result" - func_append dir "$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - # At present, this check doesn't affect windows .dll's that - # are installed into $libdir/../bin (currently, that works fine) - # but it's something to keep an eye on. - test "$inst_prefix_dir" = "$destdir" && \ - func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` - fi - - func_warning "relinking \`$file'" - func_show_eval "$relink_command" \ - 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' - fi - - # See the names of the shared library. - set dummy $library_names; shift - if test -n "$1"; then - realname="$1" - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ - 'exit $?' - tstripme="$stripme" - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - case $realname in - *.dll.a) - tstripme="" - ;; - esac - ;; - esac - if test -n "$tstripme" && test -n "$striplib"; then - func_show_eval "$striplib $destdir/$realname" 'exit $?' - fi - - if test "$#" -gt 0; then - # Delete the old symlinks, and create new ones. - # Try `ln -sf' first, because the `ln' binary might depend on - # the symlink we replace! Solaris /bin/ln does not understand -f, - # so we also need to try rm && ln -s. - for linkname - do - test "$linkname" != "$realname" \ - && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - func_execute_cmds "$postinstall_cmds" 'exit $?' - fi - - # Install the pseudo-library for information purposes. - func_basename "$file" - name="$func_basename_result" - instname="$dir/$name"i - func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' - - # Maybe install the static library, too. - test -n "$old_library" && func_append staticlibs " $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - func_lo2o "$destfile" - staticdest=$func_lo2o_result - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - func_fatal_help "cannot copy a libtool object to \`$destfile'" - ;; - esac - - # Install the libtool object if requested. - test -n "$destfile" && \ - func_show_eval "$install_prog $file $destfile" 'exit $?' - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - func_lo2o "$file" - staticobj=$func_lo2o_result - func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' - fi - exit $EXIT_SUCCESS - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - func_basename "$file" - destfile="$func_basename_result" - destfile="$destdir/$destfile" - fi - - # If the file is missing, and there is a .exe on the end, strip it - # because it is most likely a libtool script we actually want to - # install - stripped_ext="" - case $file in - *.exe) - if test ! -f "$file"; then - func_stripname '' '.exe' "$file" - file=$func_stripname_result - stripped_ext=".exe" - fi - ;; - esac - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin* | *mingw*) - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - wrapper=$func_ltwrapper_scriptname_result - else - func_stripname '' '.exe' "$file" - wrapper=$func_stripname_result - fi - ;; - *) - wrapper=$file - ;; - esac - if func_ltwrapper_script_p "$wrapper"; then - notinst_deplibs= - relink_command= - - func_source "$wrapper" - - # Check the variables that should have been set. - test -z "$generated_by_libtool_version" && \ - func_fatal_error "invalid libtool wrapper script \`$wrapper'" - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - func_source "$lib" - fi - libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - func_warning "\`$lib' has not been installed in \`$libdir'" - finalize=no - fi - done - - relink_command= - func_source "$wrapper" - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - $opt_dry_run || { - if test "$finalize" = yes; then - tmpdir=`func_mktempdir` - func_basename "$file$stripped_ext" - file="$func_basename_result" - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` - - $opt_silent || { - func_quote_for_expand "$relink_command" - eval "func_echo $func_quote_for_expand_result" - } - if eval "$relink_command"; then : - else - func_error "error: relink \`$file' with the above command before installing it" - $opt_dry_run || ${RM}r "$tmpdir" - continue - fi - file="$outputname" - else - func_warning "cannot relink \`$file'" - fi - } - else - # Install the binary that we compiled earlier. - file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyway - case $install_prog,$host in - */usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - func_stripname '' '.exe' "$destfile" - destfile=$func_stripname_result - ;; - esac - ;; - esac - func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' - $opt_dry_run || if test -n "$outputname"; then - ${RM}r "$tmpdir" - fi - ;; - esac - done - - for file in $staticlibs; do - func_basename "$file" - name="$func_basename_result" - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 - tool_oldlib=$func_to_tool_file_result - - func_show_eval "$install_prog \$file \$oldlib" 'exit $?' - - if test -n "$stripme" && test -n "$old_striplib"; then - func_show_eval "$old_striplib $tool_oldlib" 'exit $?' - fi - - # Do each command in the postinstall commands. - func_execute_cmds "$old_postinstall_cmds" 'exit $?' - done - - test -n "$future_libdirs" && \ - func_warning "remember to run \`$progname --finish$future_libdirs'" - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - $opt_dry_run && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' - else - exit $EXIT_SUCCESS - fi -} - -test "$opt_mode" = install && func_mode_install ${1+"$@"} - - -# func_generate_dlsyms outputname originator pic_p -# Extract symbols from dlprefiles and create ${outputname}S.o with -# a dlpreopen symbol table. -func_generate_dlsyms () -{ - $opt_debug - my_outputname="$1" - my_originator="$2" - my_pic_p="${3-no}" - my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` - my_dlsyms= - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - my_dlsyms="${my_outputname}S.c" - else - func_error "not configured to extract global symbols from dlpreopened files" - fi - fi - - if test -n "$my_dlsyms"; then - case $my_dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${my_outputname}.nm" - - func_show_eval "$RM $nlist ${nlist}S ${nlist}T" - - # Parse the name list into a source file. - func_verbose "creating $output_objdir/$my_dlsyms" - - $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ -/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ -/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) -#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" -#endif - -/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ -#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) -/* DATA imports from DLLs on WIN32 con't be const, because runtime - relocations are performed -- see ld's documentation on pseudo-relocs. */ -# define LT_DLSYM_CONST -#elif defined(__osf__) -/* This system does not cope well with relocations in const data. */ -# define LT_DLSYM_CONST -#else -# define LT_DLSYM_CONST const -#endif - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - func_verbose "generating symbol list for \`$output'" - - $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` - for progfile in $progfiles; do - func_to_tool_file "$progfile" func_convert_file_msys_to_w32 - func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" - $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $opt_dry_run || { - eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - if test -n "$export_symbols_regex"; then - $opt_dry_run || { - eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - } - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$outputname.exp" - $opt_dry_run || { - $RM $export_symbols - eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' - ;; - esac - } - else - $opt_dry_run || { - eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' - eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' - eval '$MV "$nlist"T "$nlist"' - case $host in - *cygwin* | *mingw* | *cegcc* ) - eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' - eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' - ;; - esac - } - fi - fi - - for dlprefile in $dlprefiles; do - func_verbose "extracting global C symbols from \`$dlprefile'" - func_basename "$dlprefile" - name="$func_basename_result" - case $host in - *cygwin* | *mingw* | *cegcc* ) - # if an import library, we need to obtain dlname - if func_win32_import_lib_p "$dlprefile"; then - func_tr_sh "$dlprefile" - eval "curr_lafile=\$libfile_$func_tr_sh_result" - dlprefile_dlbasename="" - if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then - # Use subshell, to avoid clobbering current variable values - dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` - if test -n "$dlprefile_dlname" ; then - func_basename "$dlprefile_dlname" - dlprefile_dlbasename="$func_basename_result" - else - # no lafile. user explicitly requested -dlpreopen . - $sharedlib_from_linklib_cmd "$dlprefile" - dlprefile_dlbasename=$sharedlib_from_linklib_result - fi - fi - $opt_dry_run || { - if test -n "$dlprefile_dlbasename" ; then - eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' - else - func_warning "Could not compute DLL name from $name" - eval '$ECHO ": $name " >> "$nlist"' - fi - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | - $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" - } - else # not an import lib - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - fi - ;; - *) - $opt_dry_run || { - eval '$ECHO ": $name " >> "$nlist"' - func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" - } - ;; - esac - done - - $opt_dry_run || { - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $MV "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if $GREP -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - $GREP -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' - else - echo '/* NONE */' >> "$output_objdir/$my_dlsyms" - fi - - echo >> "$output_objdir/$my_dlsyms" "\ - -/* The mapping between symbol names and symbols. */ -typedef struct { - const char *name; - void *address; -} lt_dlsymlist; -extern LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[]; -LT_DLSYM_CONST lt_dlsymlist -lt_${my_prefix}_LTX_preloaded_symbols[] = -{\ - { \"$my_originator\", (void *) 0 }," - - case $need_lib_prefix in - no) - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - *) - eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" - ;; - esac - echo >> "$output_objdir/$my_dlsyms" "\ - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_${my_prefix}_LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - } # !$opt_dry_run - - pic_flag_for_symtable= - case "$compile_command " in - *" -static "*) ;; - *) - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; - *-*-hpux*) - pic_flag_for_symtable=" $pic_flag" ;; - *) - if test "X$my_pic_p" != Xno; then - pic_flag_for_symtable=" $pic_flag" - fi - ;; - esac - ;; - esac - symtab_cflags= - for arg in $LTCFLAGS; do - case $arg in - -pie | -fpie | -fPIE) ;; - *) func_append symtab_cflags " $arg" ;; - esac - done - - # Now compile the dynamic symbol file. - func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' - - # Clean up the generated files. - func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' - - # Transform the symbol file into the correct name. - symfileobj="$output_objdir/${my_outputname}S.$objext" - case $host in - *cygwin* | *mingw* | *cegcc* ) - if test -f "$output_objdir/$my_outputname.def"; then - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` - else - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - fi - ;; - *) - compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` - ;; - esac - ;; - *) - func_fatal_error "unknown suffix for \`$my_dlsyms'" - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` - finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` - fi -} - -# func_win32_libid arg -# return the library type of file 'arg' -# -# Need a lot of goo to handle *both* DLLs and import libs -# Has to be a shell function in order to 'eat' the argument -# that is supplied when $file_magic_command is called. -# Despite the name, also deal with 64 bit binaries. -func_win32_libid () -{ - $opt_debug - win32_libid_type="unknown" - win32_fileres=`file -L $1 2>/dev/null` - case $win32_fileres in - *ar\ archive\ import\ library*) # definitely import - win32_libid_type="x86 archive import" - ;; - *ar\ archive*) # could be an import, or static - # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. - if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | - $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then - func_to_tool_file "$1" func_convert_file_msys_to_w32 - win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | - $SED -n -e ' - 1,100{ - / I /{ - s,.*,import, - p - q - } - }'` - case $win32_nmres in - import*) win32_libid_type="x86 archive import";; - *) win32_libid_type="x86 archive static";; - esac - fi - ;; - *DLL*) - win32_libid_type="x86 DLL" - ;; - *executable*) # but shell scripts are "executable" too... - case $win32_fileres in - *MS\ Windows\ PE\ Intel*) - win32_libid_type="x86 DLL" - ;; - esac - ;; - esac - $ECHO "$win32_libid_type" -} - -# func_cygming_dll_for_implib ARG -# -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib () -{ - $opt_debug - sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` -} - -# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs -# -# The is the core of a fallback implementation of a -# platform-specific function to extract the name of the -# DLL associated with the specified import library LIBNAME. -# -# SECTION_NAME is either .idata$6 or .idata$7, depending -# on the platform and compiler that created the implib. -# -# Echos the name of the DLL associated with the -# specified import library. -func_cygming_dll_for_implib_fallback_core () -{ - $opt_debug - match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` - $OBJDUMP -s --section "$1" "$2" 2>/dev/null | - $SED '/^Contents of section '"$match_literal"':/{ - # Place marker at beginning of archive member dllname section - s/.*/====MARK====/ - p - d - } - # These lines can sometimes be longer than 43 characters, but - # are always uninteresting - /:[ ]*file format pe[i]\{,1\}-/d - /^In archive [^:]*:/d - # Ensure marker is printed - /^====MARK====/p - # Remove all lines with less than 43 characters - /^.\{43\}/!d - # From remaining lines, remove first 43 characters - s/^.\{43\}//' | - $SED -n ' - # Join marker and all lines until next marker into a single line - /^====MARK====/ b para - H - $ b para - b - :para - x - s/\n//g - # Remove the marker - s/^====MARK====// - # Remove trailing dots and whitespace - s/[\. \t]*$// - # Print - /./p' | - # we now have a list, one entry per line, of the stringified - # contents of the appropriate section of all members of the - # archive which possess that section. Heuristic: eliminate - # all those which have a first or second character that is - # a '.' (that is, objdump's representation of an unprintable - # character.) This should work for all archives with less than - # 0x302f exports -- but will fail for DLLs whose name actually - # begins with a literal '.' or a single character followed by - # a '.'. - # - # Of those that remain, print the first one. - $SED -e '/^\./d;/^.\./d;q' -} - -# func_cygming_gnu_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is a GNU/binutils-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_gnu_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` - test -n "$func_cygming_gnu_implib_tmp" -} - -# func_cygming_ms_implib_p ARG -# This predicate returns with zero status (TRUE) if -# ARG is an MS-style import library. Returns -# with nonzero status (FALSE) otherwise. -func_cygming_ms_implib_p () -{ - $opt_debug - func_to_tool_file "$1" func_convert_file_msys_to_w32 - func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` - test -n "$func_cygming_ms_implib_tmp" -} - -# func_cygming_dll_for_implib_fallback ARG -# Platform-specific function to extract the -# name of the DLL associated with the specified -# import library ARG. -# -# This fallback implementation is for use when $DLLTOOL -# does not support the --identify-strict option. -# Invoked by eval'ing the libtool variable -# $sharedlib_from_linklib_cmd -# Result is available in the variable -# $sharedlib_from_linklib_result -func_cygming_dll_for_implib_fallback () -{ - $opt_debug - if func_cygming_gnu_implib_p "$1" ; then - # binutils import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` - elif func_cygming_ms_implib_p "$1" ; then - # ms-generated import library - sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` - else - # unknown - sharedlib_from_linklib_result="" - fi -} - - -# func_extract_an_archive dir oldlib -func_extract_an_archive () -{ - $opt_debug - f_ex_an_ar_dir="$1"; shift - f_ex_an_ar_oldlib="$1" - if test "$lock_old_archive_extraction" = yes; then - lockfile=$f_ex_an_ar_oldlib.lock - until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do - func_echo "Waiting for $lockfile to be removed" - sleep 2 - done - fi - func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ - 'stat=$?; rm -f "$lockfile"; exit $stat' - if test "$lock_old_archive_extraction" = yes; then - $opt_dry_run || rm -f "$lockfile" - fi - if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then - : - else - func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" - fi -} - - -# func_extract_archives gentop oldlib ... -func_extract_archives () -{ - $opt_debug - my_gentop="$1"; shift - my_oldlibs=${1+"$@"} - my_oldobjs="" - my_xlib="" - my_xabs="" - my_xdir="" - - for my_xlib in $my_oldlibs; do - # Extract the objects. - case $my_xlib in - [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; - *) my_xabs=`pwd`"/$my_xlib" ;; - esac - func_basename "$my_xlib" - my_xlib="$func_basename_result" - my_xlib_u=$my_xlib - while :; do - case " $extracted_archives " in - *" $my_xlib_u "*) - func_arith $extracted_serial + 1 - extracted_serial=$func_arith_result - my_xlib_u=lt$extracted_serial-$my_xlib ;; - *) break ;; - esac - done - extracted_archives="$extracted_archives $my_xlib_u" - my_xdir="$my_gentop/$my_xlib_u" - - func_mkdir_p "$my_xdir" - - case $host in - *-darwin*) - func_verbose "Extracting $my_xabs" - # Do not bother doing anything if just a dry run - $opt_dry_run || { - darwin_orig_dir=`pwd` - cd $my_xdir || exit $? - darwin_archive=$my_xabs - darwin_curdir=`pwd` - darwin_base_archive=`basename "$darwin_archive"` - darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` - if test -n "$darwin_arches"; then - darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` - darwin_arch= - func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" - for darwin_arch in $darwin_arches ; do - func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" - $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" - cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" - func_extract_an_archive "`pwd`" "${darwin_base_archive}" - cd "$darwin_curdir" - $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" - done # $darwin_arches - ## Okay now we've a bunch of thin objects, gotta fatten them up :) - darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` - darwin_file= - darwin_files= - for darwin_file in $darwin_filelist; do - darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` - $LIPO -create -output "$darwin_file" $darwin_files - done # $darwin_filelist - $RM -rf unfat-$$ - cd "$darwin_orig_dir" - else - cd $darwin_orig_dir - func_extract_an_archive "$my_xdir" "$my_xabs" - fi # $darwin_arches - } # !$opt_dry_run - ;; - *) - func_extract_an_archive "$my_xdir" "$my_xabs" - ;; - esac - my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` - done - - func_extract_archives_result="$my_oldobjs" -} - - -# func_emit_wrapper [arg=no] -# -# Emit a libtool wrapper script on stdout. -# Don't directly open a file because we may want to -# incorporate the script contents within a cygwin/mingw -# wrapper executable. Must ONLY be called from within -# func_mode_link because it depends on a number of variables -# set therein. -# -# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR -# variable will take. If 'yes', then the emitted script -# will assume that the directory in which it is stored is -# the $objdir directory. This is a cygwin/mingw-specific -# behavior. -func_emit_wrapper () -{ - func_emit_wrapper_arg1=${1-no} - - $ECHO "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='$sed_quote_subst' - -# Be Bourne compatible -if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then - emulate sh - NULLCMD=: - # Zsh 3.x and 4.x performs 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 -BIN_SH=xpg4; export BIN_SH # for Tru64 -DUALCASE=1; export DUALCASE # for MKS sh - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variables: - generated_by_libtool_version='$macro_version' - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$ECHO are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - file=\"\$0\"" - - qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` - $ECHO "\ - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - ECHO=\"$qECHO\" - fi - -# Very basic option parsing. These options are (a) specific to -# the libtool wrapper, (b) are identical between the wrapper -# /script/ and the wrapper /executable/ which is used only on -# windows platforms, and (c) all begin with the string "--lt-" -# (application programs are unlikely to have options which match -# this pattern). -# -# There are only two supported options: --lt-debug and -# --lt-dump-script. There is, deliberately, no --lt-help. -# -# The first argument to this parsing function should be the -# script's $0 value, followed by "$@". -lt_option_debug= -func_parse_lt_options () -{ - lt_script_arg0=\$0 - shift - for lt_opt - do - case \"\$lt_opt\" in - --lt-debug) lt_option_debug=1 ;; - --lt-dump-script) - lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` - test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. - lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` - cat \"\$lt_dump_D/\$lt_dump_F\" - exit 0 - ;; - --lt-*) - \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 - exit 1 - ;; - esac - done - - # Print the debug banner immediately: - if test -n \"\$lt_option_debug\"; then - echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 - fi -} - -# Used when --lt-debug. Prints its arguments to stdout -# (redirection is the responsibility of the caller) -func_lt_dump_args () -{ - lt_dump_args_N=1; - for lt_arg - do - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" - lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` - done -} - -# Core function for launching the target application -func_exec_program_core () -{ -" - case $host in - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2* | *-cegcc*) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} -" - ;; - - *) - $ECHO "\ - if test -n \"\$lt_option_debug\"; then - \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 - func_lt_dump_args \${1+\"\$@\"} 1>&2 - fi - exec \"\$progdir/\$program\" \${1+\"\$@\"} -" - ;; - esac - $ECHO "\ - \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 - exit 1 -} - -# A function to encapsulate launching the target application -# Strips options in the --lt-* namespace from \$@ and -# launches target application with the remaining arguments. -func_exec_program () -{ - case \" \$* \" in - *\\ --lt-*) - for lt_wr_arg - do - case \$lt_wr_arg in - --lt-*) ;; - *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; - esac - shift - done ;; - esac - func_exec_program_core \${1+\"\$@\"} -} - - # Parse options - func_parse_lt_options \"\$0\" \${1+\"\$@\"} - - # Find the directory that this script lives in. - thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` - done - - # Usually 'no', except on cygwin/mingw when embedded into - # the cwrapper. - WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 - if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then - # special case for '.' - if test \"\$thisdir\" = \".\"; then - thisdir=\`pwd\` - fi - # remove .libs from thisdir - case \"\$thisdir\" in - *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; - $objdir ) thisdir=. ;; - esac - fi - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - $ECHO "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $MKDIR \"\$progdir\" - else - $RM \"\$progdir/\$file\" - fi" - - $ECHO "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $ECHO \"\$relink_command_output\" >&2 - $RM \"\$progdir/\$file\" - exit 1 - fi - fi - - $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $RM \"\$progdir/\$program\"; - $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $RM \"\$progdir/\$file\" - fi" - else - $ECHO "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - $ECHO "\ - - if test -f \"\$progdir/\$program\"; then" - - # fixup the dll searchpath if we need to. - # - # Fix the DLL searchpath if we need to. Do this before prepending - # to shlibpath, because on Windows, both are PATH and uninstalled - # libraries must come first. - if test -n "$dllsearchpath"; then - $ECHO "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $ECHO "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` - - export $shlibpath_var -" - fi - - $ECHO "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. - func_exec_program \${1+\"\$@\"} - fi - else - # The program doesn't exist. - \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 - \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 - \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" -} - - -# func_emit_cwrapperexe_src -# emit the source code for a wrapper executable on stdout -# Must ONLY be called from within func_mode_link because -# it depends on a number of variable set therein. -func_emit_cwrapperexe_src () -{ - cat < -#include -#ifdef _MSC_VER -# include -# include -# include -#else -# include -# include -# ifdef __CYGWIN__ -# include -# endif -#endif -#include -#include -#include -#include -#include -#include -#include -#include - -/* declarations of non-ANSI functions */ -#if defined(__MINGW32__) -# ifdef __STRICT_ANSI__ -int _putenv (const char *); -# endif -#elif defined(__CYGWIN__) -# ifdef __STRICT_ANSI__ -char *realpath (const char *, char *); -int putenv (char *); -int setenv (const char *, const char *, int); -# endif -/* #elif defined (other platforms) ... */ -#endif - -/* portability defines, excluding path handling macros */ -#if defined(_MSC_VER) -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -# define S_IXUSR _S_IEXEC -# ifndef _INTPTR_T_DEFINED -# define _INTPTR_T_DEFINED -# define intptr_t int -# endif -#elif defined(__MINGW32__) -# define setmode _setmode -# define stat _stat -# define chmod _chmod -# define getcwd _getcwd -# define putenv _putenv -#elif defined(__CYGWIN__) -# define HAVE_SETENV -# define FOPEN_WB "wb" -/* #elif defined (other platforms) ... */ -#endif - -#if defined(PATH_MAX) -# define LT_PATHMAX PATH_MAX -#elif defined(MAXPATHLEN) -# define LT_PATHMAX MAXPATHLEN -#else -# define LT_PATHMAX 1024 -#endif - -#ifndef S_IXOTH -# define S_IXOTH 0 -#endif -#ifndef S_IXGRP -# define S_IXGRP 0 -#endif - -/* path handling portability macros */ -#ifndef DIR_SEPARATOR -# define DIR_SEPARATOR '/' -# define PATH_SEPARATOR ':' -#endif - -#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ - defined (__OS2__) -# define HAVE_DOS_BASED_FILE_SYSTEM -# define FOPEN_WB "wb" -# ifndef DIR_SEPARATOR_2 -# define DIR_SEPARATOR_2 '\\' -# endif -# ifndef PATH_SEPARATOR_2 -# define PATH_SEPARATOR_2 ';' -# endif -#endif - -#ifndef DIR_SEPARATOR_2 -# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) -#else /* DIR_SEPARATOR_2 */ -# define IS_DIR_SEPARATOR(ch) \ - (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) -#endif /* DIR_SEPARATOR_2 */ - -#ifndef PATH_SEPARATOR_2 -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) -#else /* PATH_SEPARATOR_2 */ -# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) -#endif /* PATH_SEPARATOR_2 */ - -#ifndef FOPEN_WB -# define FOPEN_WB "w" -#endif -#ifndef _O_BINARY -# define _O_BINARY 0 -#endif - -#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) -#define XFREE(stale) do { \ - if (stale) { free ((void *) stale); stale = 0; } \ -} while (0) - -#if defined(LT_DEBUGWRAPPER) -static int lt_debug = 1; -#else -static int lt_debug = 0; -#endif - -const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ - -void *xmalloc (size_t num); -char *xstrdup (const char *string); -const char *base_name (const char *name); -char *find_executable (const char *wrapper); -char *chase_symlinks (const char *pathspec); -int make_executable (const char *path); -int check_executable (const char *path); -char *strendzap (char *str, const char *pat); -void lt_debugprintf (const char *file, int line, const char *fmt, ...); -void lt_fatal (const char *file, int line, const char *message, ...); -static const char *nonnull (const char *s); -static const char *nonempty (const char *s); -void lt_setenv (const char *name, const char *value); -char *lt_extend_str (const char *orig_value, const char *add, int to_end); -void lt_update_exe_path (const char *name, const char *value); -void lt_update_lib_path (const char *name, const char *value); -char **prepare_spawn (char **argv); -void lt_dump_script (FILE *f); -EOF - - cat <= 0) - && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) - return 1; - else - return 0; -} - -int -make_executable (const char *path) -{ - int rval = 0; - struct stat st; - - lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", - nonempty (path)); - if ((!path) || (!*path)) - return 0; - - if (stat (path, &st) >= 0) - { - rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); - } - return rval; -} - -/* Searches for the full path of the wrapper. Returns - newly allocated full path name if found, NULL otherwise - Does not chase symlinks, even on platforms that support them. -*/ -char * -find_executable (const char *wrapper) -{ - int has_slash = 0; - const char *p; - const char *p_next; - /* static buffer for getcwd */ - char tmp[LT_PATHMAX + 1]; - int tmp_len; - char *concat_name; - - lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", - nonempty (wrapper)); - - if ((wrapper == NULL) || (*wrapper == '\0')) - return NULL; - - /* Absolute path? */ -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - else - { -#endif - if (IS_DIR_SEPARATOR (wrapper[0])) - { - concat_name = xstrdup (wrapper); - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } -#if defined (HAVE_DOS_BASED_FILE_SYSTEM) - } -#endif - - for (p = wrapper; *p; p++) - if (*p == '/') - { - has_slash = 1; - break; - } - if (!has_slash) - { - /* no slashes; search PATH */ - const char *path = getenv ("PATH"); - if (path != NULL) - { - for (p = path; *p; p = p_next) - { - const char *q; - size_t p_len; - for (q = p; *q; q++) - if (IS_PATH_SEPARATOR (*q)) - break; - p_len = q - p; - p_next = (*q == '\0' ? q : q + 1); - if (p_len == 0) - { - /* empty path: current directory */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = - XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - } - else - { - concat_name = - XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, p, p_len); - concat_name[p_len] = '/'; - strcpy (concat_name + p_len + 1, wrapper); - } - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - } - } - /* not found in PATH; assume curdir */ - } - /* Relative path | not found in path: prepend cwd */ - if (getcwd (tmp, LT_PATHMAX) == NULL) - lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", - nonnull (strerror (errno))); - tmp_len = strlen (tmp); - concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); - memcpy (concat_name, tmp, tmp_len); - concat_name[tmp_len] = '/'; - strcpy (concat_name + tmp_len + 1, wrapper); - - if (check_executable (concat_name)) - return concat_name; - XFREE (concat_name); - return NULL; -} - -char * -chase_symlinks (const char *pathspec) -{ -#ifndef S_ISLNK - return xstrdup (pathspec); -#else - char buf[LT_PATHMAX]; - struct stat s; - char *tmp_pathspec = xstrdup (pathspec); - char *p; - int has_symlinks = 0; - while (strlen (tmp_pathspec) && !has_symlinks) - { - lt_debugprintf (__FILE__, __LINE__, - "checking path component for symlinks: %s\n", - tmp_pathspec); - if (lstat (tmp_pathspec, &s) == 0) - { - if (S_ISLNK (s.st_mode) != 0) - { - has_symlinks = 1; - break; - } - - /* search backwards for last DIR_SEPARATOR */ - p = tmp_pathspec + strlen (tmp_pathspec) - 1; - while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - p--; - if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) - { - /* no more DIR_SEPARATORS left */ - break; - } - *p = '\0'; - } - else - { - lt_fatal (__FILE__, __LINE__, - "error accessing file \"%s\": %s", - tmp_pathspec, nonnull (strerror (errno))); - } - } - XFREE (tmp_pathspec); - - if (!has_symlinks) - { - return xstrdup (pathspec); - } - - tmp_pathspec = realpath (pathspec, buf); - if (tmp_pathspec == 0) - { - lt_fatal (__FILE__, __LINE__, - "could not follow symlinks for %s", pathspec); - } - return xstrdup (tmp_pathspec); -#endif -} - -char * -strendzap (char *str, const char *pat) -{ - size_t len, patlen; - - assert (str != NULL); - assert (pat != NULL); - - len = strlen (str); - patlen = strlen (pat); - - if (patlen <= len) - { - str += len - patlen; - if (strcmp (str, pat) == 0) - *str = '\0'; - } - return str; -} - -void -lt_debugprintf (const char *file, int line, const char *fmt, ...) -{ - va_list args; - if (lt_debug) - { - (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); - va_start (args, fmt); - (void) vfprintf (stderr, fmt, args); - va_end (args); - } -} - -static void -lt_error_core (int exit_status, const char *file, - int line, const char *mode, - const char *message, va_list ap) -{ - fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); - vfprintf (stderr, message, ap); - fprintf (stderr, ".\n"); - - if (exit_status >= 0) - exit (exit_status); -} - -void -lt_fatal (const char *file, int line, const char *message, ...) -{ - va_list ap; - va_start (ap, message); - lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); - va_end (ap); -} - -static const char * -nonnull (const char *s) -{ - return s ? s : "(null)"; -} - -static const char * -nonempty (const char *s) -{ - return (s && !*s) ? "(empty)" : nonnull (s); -} - -void -lt_setenv (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_setenv) setting '%s' to '%s'\n", - nonnull (name), nonnull (value)); - { -#ifdef HAVE_SETENV - /* always make a copy, for consistency with !HAVE_SETENV */ - char *str = xstrdup (value); - setenv (name, str, 1); -#else - int len = strlen (name) + 1 + strlen (value) + 1; - char *str = XMALLOC (char, len); - sprintf (str, "%s=%s", name, value); - if (putenv (str) != EXIT_SUCCESS) - { - XFREE (str); - } -#endif - } -} - -char * -lt_extend_str (const char *orig_value, const char *add, int to_end) -{ - char *new_value; - if (orig_value && *orig_value) - { - int orig_value_len = strlen (orig_value); - int add_len = strlen (add); - new_value = XMALLOC (char, add_len + orig_value_len + 1); - if (to_end) - { - strcpy (new_value, orig_value); - strcpy (new_value + orig_value_len, add); - } - else - { - strcpy (new_value, add); - strcpy (new_value + add_len, orig_value); - } - } - else - { - new_value = xstrdup (add); - } - return new_value; -} - -void -lt_update_exe_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - /* some systems can't cope with a ':'-terminated path #' */ - int len = strlen (new_value); - while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) - { - new_value[len-1] = '\0'; - } - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -void -lt_update_lib_path (const char *name, const char *value) -{ - lt_debugprintf (__FILE__, __LINE__, - "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", - nonnull (name), nonnull (value)); - - if (name && *name && value && *value) - { - char *new_value = lt_extend_str (getenv (name), value, 0); - lt_setenv (name, new_value); - XFREE (new_value); - } -} - -EOF - case $host_os in - mingw*) - cat <<"EOF" - -/* Prepares an argument vector before calling spawn(). - Note that spawn() does not by itself call the command interpreter - (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : - ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&v); - v.dwPlatformId == VER_PLATFORM_WIN32_NT; - }) ? "cmd.exe" : "command.com"). - Instead it simply concatenates the arguments, separated by ' ', and calls - CreateProcess(). We must quote the arguments since Win32 CreateProcess() - interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a - special way: - - Space and tab are interpreted as delimiters. They are not treated as - delimiters if they are surrounded by double quotes: "...". - - Unescaped double quotes are removed from the input. Their only effect is - that within double quotes, space and tab are treated like normal - characters. - - Backslashes not followed by double quotes are not special. - - But 2*n+1 backslashes followed by a double quote become - n backslashes followed by a double quote (n >= 0): - \" -> " - \\\" -> \" - \\\\\" -> \\" - */ -#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" -char ** -prepare_spawn (char **argv) -{ - size_t argc; - char **new_argv; - size_t i; - - /* Count number of arguments. */ - for (argc = 0; argv[argc] != NULL; argc++) - ; - - /* Allocate new argument vector. */ - new_argv = XMALLOC (char *, argc + 1); - - /* Put quoted arguments into the new argument vector. */ - for (i = 0; i < argc; i++) - { - const char *string = argv[i]; - - if (string[0] == '\0') - new_argv[i] = xstrdup ("\"\""); - else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) - { - int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); - size_t length; - unsigned int backslashes; - const char *s; - char *quoted_string; - char *p; - - length = 0; - backslashes = 0; - if (quote_around) - length++; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - length += backslashes + 1; - length++; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - length += backslashes + 1; - - quoted_string = XMALLOC (char, length + 1); - - p = quoted_string; - backslashes = 0; - if (quote_around) - *p++ = '"'; - for (s = string; *s != '\0'; s++) - { - char c = *s; - if (c == '"') - { - unsigned int j; - for (j = backslashes + 1; j > 0; j--) - *p++ = '\\'; - } - *p++ = c; - if (c == '\\') - backslashes++; - else - backslashes = 0; - } - if (quote_around) - { - unsigned int j; - for (j = backslashes; j > 0; j--) - *p++ = '\\'; - *p++ = '"'; - } - *p = '\0'; - - new_argv[i] = quoted_string; - } - else - new_argv[i] = (char *) string; - } - new_argv[argc] = NULL; - - return new_argv; -} -EOF - ;; - esac - - cat <<"EOF" -void lt_dump_script (FILE* f) -{ -EOF - func_emit_wrapper yes | - $SED -n -e ' -s/^\(.\{79\}\)\(..*\)/\1\ -\2/ -h -s/\([\\"]\)/\\\1/g -s/$/\\n/ -s/\([^\n]*\).*/ fputs ("\1", f);/p -g -D' - cat <<"EOF" -} -EOF -} -# end: func_emit_cwrapperexe_src - -# func_win32_import_lib_p ARG -# True if ARG is an import lib, as indicated by $file_magic_cmd -func_win32_import_lib_p () -{ - $opt_debug - case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in - *import*) : ;; - *) false ;; - esac -} - -# func_mode_link arg... -func_mode_link () -{ - $opt_debug - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra - # flag for every libtool invocation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args=$nonopt - base_compile="$nonopt $@" - compile_command=$nonopt - finalize_command=$nonopt - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - inst_prefix_dir= - new_inherited_linker_flags= - - avoid_version=no - bindir= - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - non_pic_objects= - precious_files_regex= - prefer_static_libs=no - preload=no - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - vinfo_number=no - weak_libs= - single_module="${wl}-single_module" - func_infer_tag $base_compile - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -shared) - test "$build_libtool_libs" != yes && \ - func_fatal_configuration "can not build a shared library" - build_old_libs=no - break - ;; - -all-static | -static | -static-libtool-libs) - case $arg in - -all-static) - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then - func_warning "complete static linking is impossible in this configuration" - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - -static) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=built - ;; - -static-libtool-libs) - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - prefer_static_libs=yes - ;; - esac - build_libtool_libs=no - build_old_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test "$#" -gt 0; do - arg="$1" - shift - func_quote_for_eval "$arg" - qarg=$func_quote_for_eval_unquoted_result - func_append libtool_args " $func_quote_for_eval_result" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - func_append compile_command " @OUTPUT@" - func_append finalize_command " @OUTPUT@" - ;; - esac - - case $prev in - bindir) - bindir="$arg" - prev= - continue - ;; - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - func_append compile_command " @SYMFILE@" - func_append finalize_command " @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - func_append dlfiles " $arg" - else - func_append dlprefiles " $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - test -f "$arg" \ - || func_fatal_error "symbol file \`$arg' does not exist" - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - framework) - case $host in - *-*-darwin*) - case "$deplibs " in - *" $qarg.ltframework "*) ;; - *) func_append deplibs " $qarg.ltframework" # this is fixed later - ;; - esac - ;; - esac - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - objectlist) - if test -f "$arg"; then - save_arg=$arg - moreargs= - for fil in `cat "$save_arg"` - do -# func_append moreargs " $fil" - arg=$fil - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "\`$arg' is not a valid libtool object" - fi - fi - done - else - func_fatal_error "link input file \`$arg' does not exist" - fi - arg=$save_arg - prev= - continue - ;; - precious_regex) - precious_files_regex="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) func_append rpath " $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) func_append xrpath " $arg" ;; - esac - fi - prev= - continue - ;; - shrext) - shrext_cmds="$arg" - prev= - continue - ;; - weak) - func_append weak_libs " $arg" - prev= - continue - ;; - xcclinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xcompiler) - func_append compiler_flags " $qarg" - prev= - func_append compile_command " $qarg" - func_append finalize_command " $qarg" - continue - ;; - xlinker) - func_append linker_flags " $qarg" - func_append compiler_flags " $wl$qarg" - prev= - func_append compile_command " $wl$qarg" - func_append finalize_command " $wl$qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n "$prev" - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - # See comment for -static flag below, for more details. - func_append compile_command " $link_static_flag" - func_append finalize_command " $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - func_fatal_error "\`-allow-undefined' must not be used because it is the default" - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -bindir) - prev=bindir - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - func_fatal_error "more than one -exported-symbols argument is not allowed" - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -framework) - prev=framework - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | /*-*-irix*) - func_append compile_command " $arg" - func_append finalize_command " $arg" - ;; - esac - continue - ;; - - -L*) - func_stripname "-L" '' "$arg" - if test -z "$func_stripname_result"; then - if test "$#" -gt 0; then - func_fatal_error "require no space between \`-L' and \`$1'" - else - func_fatal_error "need path for \`-L' option" - fi - fi - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - test -z "$absdir" && \ - func_fatal_error "cannot determine absolute directory name of \`$dir'" - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "* | *" $arg "*) - # Will only happen for absolute or sysroot arguments - ;; - *) - # Preserve sysroot, but never include relative directories - case $dir in - [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; - *) func_append deplibs " -L$dir" ;; - esac - func_append lib_search_path " $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$dir:"*) ;; - ::) dllsearchpath=$dir;; - *) func_append dllsearchpath ":$dir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C and math libraries are in the System framework - func_append deplibs " System.ltframework" - continue - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - test "X$arg" = "X-lc" && continue - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - test "X$arg" = "X-lc" && continue - ;; - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - func_append deplibs " $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - # Tru64 UNIX uses -model [arg] to determine the layout of C++ - # classes, name mangling, and exception handling. - # Darwin uses the -arch flag to determine output architecture. - -model|-arch|-isysroot|--sysroot) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - prev=xcompiler - continue - ;; - - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - func_append compiler_flags " $arg" - func_append compile_command " $arg" - func_append finalize_command " $arg" - case "$new_inherited_linker_flags " in - *" $arg "*) ;; - * ) func_append new_inherited_linker_flags " $arg" ;; - esac - continue - ;; - - -multi_module) - single_module="${wl}-multi_module" - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) - # The PATH hackery in wrapper scripts is required on Windows - # and Darwin in order for the loader to find any dlls it needs. - func_warning "\`-no-install' is ignored for $host" - func_warning "assuming \`-no-fast-install' instead" - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -objectlist) - prev=objectlist - continue - ;; - - -o) prev=output ;; - - -precious-files-regex) - prev=precious_regex - continue - ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - func_stripname '-R' '' "$arg" - dir=$func_stripname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - =*) - func_stripname '=' '' "$dir" - dir=$lt_sysroot$func_stripname_result - ;; - *) - func_fatal_error "only absolute run-paths are allowed" - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - continue - ;; - - -shared) - # The effects of -shared are defined in a previous loop. - continue - ;; - - -shrext) - prev=shrext - continue - ;; - - -static | -static-libtool-libs) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - - -version-number) - prev=vinfo - vinfo_number=yes - continue - ;; - - -weak) - prev=weak - continue - ;; - - -Wc,*) - func_stripname '-Wc,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - func_quote_for_eval "$flag" - func_append arg " $func_quote_for_eval_result" - func_append compiler_flags " $func_quote_for_eval_result" - done - IFS="$save_ifs" - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Wl,*) - func_stripname '-Wl,' '' "$arg" - args=$func_stripname_result - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - func_quote_for_eval "$flag" - func_append arg " $wl$func_quote_for_eval_result" - func_append compiler_flags " $wl$func_quote_for_eval_result" - func_append linker_flags " $func_quote_for_eval_result" - done - IFS="$save_ifs" - func_stripname ' ' '' "$arg" - arg=$func_stripname_result - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - -XCClinker) - prev=xcclinker - continue - ;; - - # -msg_* for osf cc - -msg_*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - - # Flags to be passed through unchanged, with rationale: - # -64, -mips[0-9] enable 64-bit mode for the SGI compiler - # -r[0-9][0-9]* specify processor for the SGI compiler - # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler - # +DA*, +DD* enable 64-bit mode for the HP compiler - # -q* compiler args for the IBM compiler - # -m*, -t[45]*, -txscale* architecture-specific flags for GCC - # -F/path path to uninstalled frameworks, gcc on darwin - # -p, -pg, --coverage, -fprofile-* profiling flags for GCC - # @file GCC response files - # -tp=* Portland pgcc target processor selection - # --sysroot=* for sysroot support - # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization - -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ - -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ - -O*|-flto*|-fwhopr*|-fuse-linker-plugin) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - func_append compile_command " $arg" - func_append finalize_command " $arg" - func_append compiler_flags " $arg" - continue - ;; - - # Some other compiler flag. - -* | +*) - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - - *.$objext) - # A standard object. - func_append objs " $arg" - ;; - - *.lo) - # A libtool-controlled object. - - # Check to see that this really is a libtool object. - if func_lalib_unsafe_p "$arg"; then - pic_object= - non_pic_object= - - # Read the .lo file - func_source "$arg" - - if test -z "$pic_object" || - test -z "$non_pic_object" || - test "$pic_object" = none && - test "$non_pic_object" = none; then - func_fatal_error "cannot find name of object for \`$arg'" - fi - - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - if test "$pic_object" != none; then - # Prepend the subdirectory the object is found in. - pic_object="$xdir$pic_object" - - if test "$prev" = dlfiles; then - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - func_append dlfiles " $pic_object" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - # CHECK ME: I think I busted this. -Ossama - if test "$prev" = dlprefiles; then - # Preload the old-style object. - func_append dlprefiles " $pic_object" - prev= - fi - - # A PIC object. - func_append libobjs " $pic_object" - arg="$pic_object" - fi - - # Non-PIC object. - if test "$non_pic_object" != none; then - # Prepend the subdirectory the object is found in. - non_pic_object="$xdir$non_pic_object" - - # A standard non-PIC object - func_append non_pic_objects " $non_pic_object" - if test -z "$pic_object" || test "$pic_object" = none ; then - arg="$non_pic_object" - fi - else - # If the PIC object exists, use it instead. - # $xdir was prepended to $pic_object above. - non_pic_object="$pic_object" - func_append non_pic_objects " $non_pic_object" - fi - else - # Only an error if not doing a dry-run. - if $opt_dry_run; then - # Extract subdirectory from the argument. - func_dirname "$arg" "/" "" - xdir="$func_dirname_result" - - func_lo2o "$arg" - pic_object=$xdir$objdir/$func_lo2o_result - non_pic_object=$xdir$func_lo2o_result - func_append libobjs " $pic_object" - func_append non_pic_objects " $non_pic_object" - else - func_fatal_error "\`$arg' is not a valid libtool object" - fi - fi - ;; - - *.$libext) - # An archive. - func_append deplibs " $arg" - func_append old_deplibs " $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - func_resolve_sysroot "$arg" - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - func_append dlfiles " $func_resolve_sysroot_result" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - func_append dlprefiles " $func_resolve_sysroot_result" - prev= - else - func_append deplibs " $func_resolve_sysroot_result" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - func_quote_for_eval "$arg" - arg="$func_quote_for_eval_result" - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - done # argument parsing loop - - test -n "$prev" && \ - func_fatal_help "the \`$prevarg' option requires an argument" - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - func_append compile_command " $arg" - func_append finalize_command " $arg" - fi - - oldlibs= - # calculate the name of the file, without its directory - func_basename "$output" - outputname="$func_basename_result" - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - func_dirname "$output" "/" "" - output_objdir="$func_dirname_result$objdir" - func_to_tool_file "$output_objdir/" - tool_output_objdir=$func_to_tool_file_result - # Create the object directory. - func_mkdir_p "$output_objdir" - - # Determine the type of output - case $output in - "") - func_fatal_help "you must specify an output file" - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - specialdeplibs= - - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if $opt_preserve_dup_deps ; then - case "$libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append libs " $deplib" - done - - if test "$linkmode" = lib; then - libs="$predeps $libs $compiler_lib_search_path $postdeps" - - # Compute libraries that are listed more than once in $predeps - # $postdeps and mark them as special (i.e., whose duplicates are - # not to be eliminated). - pre_post_deps= - if $opt_duplicate_compiler_generated_deps; then - for pre_post_dep in $predeps $postdeps; do - case "$pre_post_deps " in - *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; - esac - func_append pre_post_deps " $pre_post_dep" - done - fi - pre_post_deps= - fi - - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - - case $linkmode in - lib) - passes="conv dlpreopen link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - - for pass in $passes; do - # The preopen pass in lib mode reverses $deplibs; put it back here - # so that -L comes before libs that need it for instance... - if test "$linkmode,$pass" = "lib,link"; then - ## FIXME: Find the place where the list is rebuilt in the wrong - ## order, and fix it there properly - tmp_deplibs= - for deplib in $deplibs; do - tmp_deplibs="$deplib $tmp_deplibs" - done - deplibs="$tmp_deplibs" - fi - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan"; then - libs="$deplibs" - deplibs= - fi - if test "$linkmode" = prog; then - case $pass in - dlopen) libs="$dlfiles" ;; - dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - if test "$linkmode,$pass" = "lib,dlpreopen"; then - # Collect and forward deplibs of preopened libtool libs - for lib in $dlprefiles; do - # Ignore non-libtool-libs - dependency_libs= - func_resolve_sysroot "$lib" - case $lib in - *.la) func_source "$func_resolve_sysroot_result" ;; - esac - - # Collect preopened libtool deplibs, except any this library - # has declared as weak libs - for deplib in $dependency_libs; do - func_basename "$deplib" - deplib_base=$func_basename_result - case " $weak_libs " in - *" $deplib_base "*) ;; - *) func_append deplibs " $deplib" ;; - esac - done - done - libs="$dlprefiles" - fi - if test "$pass" = dlopen; then - # Collect dlpreopened libraries - save_deplibs="$deplibs" - deplibs= - fi - - for deplib in $libs; do - lib= - found=no - case $deplib in - -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ - |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append compiler_flags " $deplib" - if test "$linkmode" = lib ; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -l*) - if test "$linkmode" != lib && test "$linkmode" != prog; then - func_warning "\`-l' is ignored for archives/objects" - continue - fi - func_stripname '-l' '' "$deplib" - name=$func_stripname_result - if test "$linkmode" = lib; then - searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" - else - searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" - fi - for searchdir in $searchdirs; do - for search_ext in .la $std_shrext .so .a; do - # Search the libtool library - lib="$searchdir/lib${name}${search_ext}" - if test -f "$lib"; then - if test "$search_ext" = ".la"; then - found=yes - else - found=no - fi - break 2 - fi - done - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - else # deplib is a libtool library - # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, - # We need to do some special things here, and not later. - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $deplib "*) - if func_lalib_p "$lib"; then - library_names= - old_library= - func_source "$lib" - for l in $old_library $library_names; do - ll="$l" - done - if test "X$ll" = "X$old_library" ; then # only static version available - found=no - func_dirname "$lib" "" "." - ladir="$func_dirname_result" - lib=$ladir/$old_library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - fi - ;; - *) ;; - esac - fi - fi - ;; # -l - *.ltframework) - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - if test "$linkmode" = lib ; then - case "$new_inherited_linker_flags " in - *" $deplib "*) ;; - * ) func_append new_inherited_linker_flags " $deplib" ;; - esac - fi - fi - continue - ;; - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test "$pass" = conv && continue - newdependency_libs="$deplib $newdependency_libs" - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - prog) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test "$pass" = scan; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - *) - func_warning "\`-L' is ignored for archives/objects" - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test "$pass" = link; then - func_stripname '-R' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - dir=$func_resolve_sysroot_result - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) func_append xrpath " $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) - func_resolve_sysroot "$deplib" - lib=$func_resolve_sysroot_result - ;; - *.$libext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - # Linking convenience modules into shared libraries is allowed, - # but linking other static libraries is non-portable. - case " $dlpreconveniencelibs " in - *" $deplib "*) ;; - *) - valid_a_lib=no - case $deplibs_check_method in - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ - | $EGREP "$match_pattern_regex" > /dev/null; then - valid_a_lib=yes - fi - ;; - pass_all) - valid_a_lib=yes - ;; - esac - if test "$valid_a_lib" != yes; then - echo - $ECHO "*** Warning: Trying to link with static lib archive $deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because the file extensions .$libext of this argument makes me believe" - echo "*** that it is just a static archive that I should not use here." - else - echo - $ECHO "*** Warning: Linking the shared library $output against the" - $ECHO "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - ;; - esac - continue - ;; - prog) - if test "$pass" != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test "$pass" = conv; then - deplibs="$deplib $deplibs" - elif test "$linkmode" = prog; then - if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - func_append newdlprefiles " $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - func_append newdlfiles " $deplib" - fi - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - - if test "$found" = yes || test -f "$lib"; then : - else - func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" - fi - - # Check to see that this really is a libtool archive. - func_lalib_unsafe_p "$lib" \ - || func_fatal_error "\`$lib' is not a valid libtool archive" - - func_dirname "$lib" "" "." - ladir="$func_dirname_result" - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - inherited_linker_flags= - # If the library was installed with an old release of libtool, - # it will not redefine variables installed, or shouldnotlink - installed=yes - shouldnotlink=no - avoidtemprpath= - - - # Read the .la file - func_source "$lib" - - # Convert "-framework foo" to "foo.ltframework" - if test -n "$inherited_linker_flags"; then - tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` - for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do - case " $new_inherited_linker_flags " in - *" $tmp_inherited_linker_flag "*) ;; - *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; - esac - done - fi - dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test "$linkmode" != prog && test "$linkmode" != lib; }; then - test -n "$dlopen" && func_append dlfiles " $dlopen" - test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" - fi - - if test "$pass" = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - func_fatal_error "cannot find name of link library for \`$lib'" - fi - # It is a libtool convenience library, so add in its objects. - func_append convenience " $ladir/$objdir/$old_library" - func_append old_convenience " $ladir/$objdir/$old_library" - elif test "$linkmode" != prog && test "$linkmode" != lib; then - func_fatal_error "\`$lib' is not a convenience library" - fi - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done - continue - fi # $pass = conv - - - # Get the name of the library we link against. - linklib= - if test -n "$old_library" && - { test "$prefer_static_libs" = yes || - test "$prefer_static_libs,$installed" = "built,no"; }; then - linklib=$old_library - else - for l in $old_library $library_names; do - linklib="$l" - done - fi - if test -z "$linklib"; then - func_fatal_error "cannot find name of link library for \`$lib'" - fi - - # This library was specified with -dlopen. - if test "$pass" = dlopen; then - if test -z "$libdir"; then - func_fatal_error "cannot -dlopen a convenience library: \`$lib'" - fi - if test -z "$dlname" || - test "$dlopen_support" != yes || - test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. We also need to preload any - # dependent libraries so libltdl's deplib preloader doesn't - # bomb out in the load deplibs phase. - func_append dlprefiles " $lib $dependency_libs" - else - func_append newdlfiles " $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - func_warning "cannot determine absolute directory name of \`$ladir'" - func_warning "passing it literally to the linker, although it might fail" - abs_ladir="$ladir" - fi - ;; - esac - func_basename "$lib" - laname="$func_basename_result" - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - func_warning "library \`$lib' was moved." - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$lt_sysroot$libdir" - absdir="$lt_sysroot$libdir" - fi - test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes - else - if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then - dir="$ladir" - absdir="$abs_ladir" - # Remove this search path later - func_append notinst_path " $abs_ladir" - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - func_append notinst_path " $abs_ladir" - fi - fi # $installed = yes - func_stripname 'lib' '.la' "$laname" - name=$func_stripname_result - - # This library was specified with -dlpreopen. - if test "$pass" = dlpreopen; then - if test -z "$libdir" && test "$linkmode" = prog; then - func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" - fi - case "$host" in - # special handling for platforms with PE-DLLs. - *cygwin* | *mingw* | *cegcc* ) - # Linker will automatically link against shared library if both - # static and shared are present. Therefore, ensure we extract - # symbols from the import library if a shared library is present - # (otherwise, the dlopen module name will be incorrect). We do - # this by putting the import library name into $newdlprefiles. - # We recover the dlopen module name by 'saving' the la file - # name in a special purpose variable, and (later) extracting the - # dlname from the la file. - if test -n "$dlname"; then - func_tr_sh "$dir/$linklib" - eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" - func_append newdlprefiles " $dir/$linklib" - else - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - fi - ;; - * ) - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - func_append newdlprefiles " $dir/$old_library" - # Keep a list of preopened convenience libraries to check - # that they are being used correctly in the link pass. - test -z "$libdir" && \ - func_append dlpreconveniencelibs " $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - func_append newdlprefiles " $dir/$dlname" - else - func_append newdlprefiles " $dir/$linklib" - fi - ;; - esac - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test "$linkmode" = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" # used for prog,scan pass - fi - continue - fi - - - if test "$linkmode" = prog && test "$pass" != link; then - func_append newlib_search_path " $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result" - func_append newlib_search_path " $func_resolve_sysroot_result" - ;; - esac - # Need to link against all dependency_libs? - if test "$linkalldeplibs" = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $deplib "*) func_append specialdeplibs " $deplib" ;; - esac - fi - func_append tmp_libs " $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - if test "$linkmode,$pass" = "prog,link"; then - if test -n "$library_names" && - { { test "$prefer_static_libs" = no || - test "$prefer_static_libs,$installed" = "built,yes"; } || - test -z "$old_library"; }; then - # We need to hardcode the library path - if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath:" in - *"$absdir:"*) ;; - *) func_append temp_rpath "$absdir:" ;; - esac - fi - - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - fi - - link_static=no # Whether the deplib will be linked statically - use_static_libs=$prefer_static_libs - if test "$use_static_libs" = built && test "$installed" = yes; then - use_static_libs=no - fi - if test -n "$library_names" && - { test "$use_static_libs" = no || test -z "$old_library"; }; then - case $host in - *cygwin* | *mingw* | *cegcc*) - # No point in relinking DLLs because paths are not encoded - func_append notinst_deplibs " $lib" - need_relink=no - ;; - *) - if test "$installed" = no; then - func_append notinst_deplibs " $lib" - need_relink=yes - fi - ;; - esac - # This is a shared library - - # Warn about portability, can't link against -module's on some - # systems (darwin). Don't bleat about dlopened modules though! - dlopenmodule="" - for dlpremoduletest in $dlprefiles; do - if test "X$dlpremoduletest" = "X$lib"; then - dlopenmodule="$dlpremoduletest" - break - fi - done - if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then - echo - if test "$linkmode" = prog; then - $ECHO "*** Warning: Linking the executable $output against the loadable module" - else - $ECHO "*** Warning: Linking the shared library $output against the loadable module" - fi - $ECHO "*** $linklib is not portable!" - fi - if test "$linkmode" = lib && - test "$hardcode_into_libs" = yes; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) func_append compile_rpath " $absdir" ;; - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - ;; - esac - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - shift - realname="$1" - shift - libname=`eval "\\$ECHO \"$libname_spec\""` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin* | mingw* | *cegcc*) - func_arith $current - $age - major=$func_arith_result - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - func_basename "$soroot" - soname="$func_basename_result" - func_stripname 'lib' '.dll' "$soname" - newlib=libimp-$func_stripname_result.a - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - func_verbose "extracting exported symbol list from \`$soname'" - func_execute_cmds "$extract_expsyms_cmds" 'exit $?' - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - func_verbose "generating import library for \`$soname'" - func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n "$old_archive_from_expsyms_cmds" - - if test "$linkmode" = prog || test "$opt_mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - case $host in - *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; - *-*-sysv4*uw2*) add_dir="-L$dir" ;; - *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ - *-*-unixware7*) add_dir="-L$dir" ;; - *-*-darwin* ) - # if the lib is a (non-dlopened) module then we can not - # link against it, someone is ignoring the earlier warnings - if /usr/bin/file -L $add 2> /dev/null | - $GREP ": [^:]* bundle" >/dev/null ; then - if test "X$dlopenmodule" != "X$lib"; then - $ECHO "*** Warning: lib $linklib is a module, not a shared library" - if test -z "$old_library" ; then - echo - echo "*** And there doesn't seem to be a static archive available" - echo "*** The link will probably fail, sorry" - else - add="$dir/$old_library" - fi - elif test -n "$old_library"; then - add="$dir/$old_library" - fi - fi - esac - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$absdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - func_fatal_configuration "unsupported hardcode properties" - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) func_append compile_shlibpath "$add_shlibpath:" ;; - esac - fi - if test "$linkmode" = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && - test "$hardcode_minus_L" != yes && - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - fi - fi - fi - - if test "$linkmode" = prog || test "$opt_mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes && - test "$hardcode_direct_absolute" = no; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) func_append finalize_shlibpath "$libdir:" ;; - esac - add="-l$name" - elif test "$hardcode_automatic" = yes; then - if test -n "$inst_prefix_dir" && - test -f "$inst_prefix_dir$libdir/$linklib" ; then - add="$inst_prefix_dir$libdir/$linklib" - else - add="$libdir/$linklib" - fi - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - # Try looking first in the location we're being installed to. - if test -n "$inst_prefix_dir"; then - case $libdir in - [\\/]*) - func_append add_dir " -L$inst_prefix_dir$libdir" - ;; - esac - fi - add="-l$name" - fi - - if test "$linkmode" = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test "$linkmode" = prog; then - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - echo - $ECHO "*** Warning: This system can not link to static lib archive $lib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - echo "*** But as you try to build a module library, libtool will still create " - echo "*** a static module, that should work as long as the dlopening application" - echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test "$linkmode" = lib; then - if test -n "$dependency_libs" && - { test "$hardcode_into_libs" != yes || - test "$build_old_libs" = yes || - test "$link_static" = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) func_stripname '-R' '' "$libdir" - temp_xrpath=$func_stripname_result - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) func_append xrpath " $temp_xrpath";; - esac;; - *) func_append temp_deplibs " $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - func_append newlib_search_path " $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - case $deplib in - -L*) func_stripname '-L' '' "$deplib" - func_resolve_sysroot "$func_stripname_result";; - *) func_resolve_sysroot "$deplib" ;; - esac - if $opt_preserve_dup_deps ; then - case "$tmp_libs " in - *" $func_resolve_sysroot_result "*) - func_append specialdeplibs " $func_resolve_sysroot_result" ;; - esac - fi - func_append tmp_libs " $func_resolve_sysroot_result" - done - - if test "$link_all_deplibs" != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - path= - case $deplib in - -L*) path="$deplib" ;; - *.la) - func_resolve_sysroot "$deplib" - deplib=$func_resolve_sysroot_result - func_dirname "$deplib" "" "." - dir=$func_dirname_result - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - func_warning "cannot determine absolute directory name of \`$dir'" - absdir="$dir" - fi - ;; - esac - if $GREP "^installed=no" $deplib > /dev/null; then - case $host in - *-*-darwin*) - depdepl= - eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` - if test -n "$deplibrary_names" ; then - for tmp in $deplibrary_names ; do - depdepl=$tmp - done - if test -f "$absdir/$objdir/$depdepl" ; then - depdepl="$absdir/$objdir/$depdepl" - darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - if test -z "$darwin_install_name"; then - darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` - fi - func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" - func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" - path= - fi - fi - ;; - *) - path="-L$absdir/$objdir" - ;; - esac - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" - test "$absdir" != "$libdir" && \ - func_warning "\`$deplib' seems to be moved" - - path="-L$absdir" - fi - ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$path $deplibs" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - if test "$pass" = link; then - if test "$linkmode" = "prog"; then - compile_deplibs="$new_inherited_linker_flags $compile_deplibs" - finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" - else - compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - fi - fi - dependency_libs="$newdependency_libs" - if test "$pass" = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test "$pass" != dlopen; then - if test "$pass" != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) func_append lib_search_path " $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - # FIXME: Pedantically, this is the right thing to do, so - # that some nasty dependency loop isn't accidentally - # broken: - #new_libs="$deplib $new_libs" - # Pragmatically, this seems to cause very few problems in - # practice: - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - -R*) ;; - *) - # And here is the reason: when a library appears more - # than once as an explicit dependence of a library, or - # is implicitly linked in more than once by the - # compiler, it is considered special, and multiple - # occurrences thereof are not removed. Compare this - # with having the same library being listed as a - # dependency of multiple other libraries: in this case, - # we know (pedantically, we assume) the library does not - # need to be listed more than once, so we keep only the - # last copy. This is not always right, but it is rare - # enough that we require users that really mean to play - # such unportable linking tricks to link the library - # using -Wl,-lname, so that libtool does not consider it - # for duplicate removal. - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) func_append tmp_libs " $deplib" ;; - esac - ;; - *) func_append tmp_libs " $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - # Last step: remove runtime libs from dependency_libs - # (they stay in deplibs) - tmp_libs= - for i in $dependency_libs ; do - case " $predeps $postdeps $compiler_lib_search_path " in - *" $i "*) - i="" - ;; - esac - if test -n "$i" ; then - func_append tmp_libs " $i" - fi - done - dependency_libs=$tmp_libs - done # for pass - if test "$linkmode" = prog; then - dlfiles="$newdlfiles" - fi - if test "$linkmode" = prog || test "$linkmode" = lib; then - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for archives" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for archives" ;; - esac - - test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for archives" - - test -n "$xrpath" && \ - func_warning "\`-R' is ignored for archives" - - test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for archives" - - test -n "$release" && \ - func_warning "\`-release' is ignored for archives" - - test -n "$export_symbols$export_symbols_regex" && \ - func_warning "\`-export-symbols' is ignored for archives" - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - func_append objs "$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - func_stripname 'lib' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - ;; - *) - test "$module" = no && \ - func_fatal_help "libtool library \`$output' must begin with \`lib'" - - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - func_stripname '' '.la' "$outputname" - name=$func_stripname_result - eval shared_ext=\"$shrext_cmds\" - eval libname=\"$libname_spec\" - else - func_stripname '' '.la' "$outputname" - libname=$func_stripname_result - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" - else - echo - $ECHO "*** Warning: Linking the shared library $output against the non-libtool" - $ECHO "*** objects $objs is not portable!" - func_append libobjs " $objs" - fi - fi - - test "$dlself" != no && \ - func_warning "\`-dlopen self' is ignored for libtool libraries" - - set dummy $rpath - shift - test "$#" -gt 1 && \ - func_warning "ignoring multiple \`-rpath's for a libtool library" - - install_libdir="$1" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - # Some compilers have problems with a `.al' extension so - # convenience libraries should have the same extension an - # archive normally would. - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - test -n "$vinfo" && \ - func_warning "\`-version-info/-version-number' is ignored for convenience libraries" - - test -n "$release" && \ - func_warning "\`-release' is ignored for convenience libraries" - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - shift - IFS="$save_ifs" - - test -n "$7" && \ - func_fatal_help "too many parameters to \`-version-info'" - - # convert absolute version numbers to libtool ages - # this retains compatibility with .la files and attempts - # to make the code below a bit more comprehensible - - case $vinfo_number in - yes) - number_major="$1" - number_minor="$2" - number_revision="$3" - # - # There are really only two kinds -- those that - # use the current revision as the major version - # and those that subtract age and use age as - # a minor version. But, then there is irix - # which has an extra 1 added just for fun - # - case $version_type in - # correct linux to gnu/linux during the next big refactor - darwin|linux|osf|windows|none) - func_arith $number_major + $number_minor - current=$func_arith_result - age="$number_minor" - revision="$number_revision" - ;; - freebsd-aout|freebsd-elf|qnx|sunos) - current="$number_major" - revision="$number_minor" - age="0" - ;; - irix|nonstopux) - func_arith $number_major + $number_minor - current=$func_arith_result - age="$number_minor" - revision="$number_minor" - lt_irix_increment=no - ;; - esac - ;; - no) - current="$1" - revision="$2" - age="$3" - ;; - esac - - # Check that each of the things are valid numbers. - case $current in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "CURRENT \`$current' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - case $revision in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "REVISION \`$revision' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - case $age in - 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; - *) - func_error "AGE \`$age' must be a nonnegative integer" - func_fatal_error "\`$vinfo' is not valid version information" - ;; - esac - - if test "$age" -gt "$current"; then - func_error "AGE \`$age' is greater than the current interface number \`$current'" - func_fatal_error "\`$vinfo' is not valid version information" - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - func_arith $current - $age - major=.$func_arith_result - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - func_arith $current + 1 - minor_current=$func_arith_result - xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current" - ;; - - irix | nonstopux) - if test "X$lt_irix_increment" = "Xno"; then - func_arith $current - $age - else - func_arith $current - $age + 1 - fi - major=$func_arith_result - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test "$loop" -ne 0; do - func_arith $revision - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) # correct to gnu/linux during the next big refactor - func_arith $current - $age - major=.$func_arith_result - versuffix="$major.$age.$revision" - ;; - - osf) - func_arith $current - $age - major=.$func_arith_result - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test "$loop" -ne 0; do - func_arith $current - $loop - iface=$func_arith_result - func_arith $loop - 1 - loop=$func_arith_result - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - func_append verstring ":${current}.0" - ;; - - qnx) - major=".$current" - versuffix=".$current" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - func_arith $current - $age - major=$func_arith_result - versuffix="-$major" - ;; - - *) - func_fatal_configuration "unknown library version type \`$version_type'" - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring= - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - func_warning "undefined symbols not allowed in $host shared libraries" - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - - fi - - func_generate_dlsyms "$libname" "$libname" "yes" - func_append libobjs " $symfileobj" - test "X$libobjs" = "X " && libobjs= - - if test "$opt_mode" != relink; then - # Remove our outputs, but don't remove object files since they - # may have been created when compiling PIC objects. - removelist= - tempremovelist=`$ECHO "$output_objdir/*"` - for p in $tempremovelist; do - case $p in - *.$objext | *.gcno) - ;; - $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) - if test "X$precious_files_regex" != "X"; then - if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 - then - continue - fi - fi - func_append removelist " $p" - ;; - *) ;; - esac - done - test -n "$removelist" && \ - func_show_eval "${RM}r \$removelist" - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - func_append oldlibs " $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - #for path in $notinst_path; do - # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` - # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` - # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` - #done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - func_replace_sysroot "$libdir" - func_append temp_xrpath " -R$func_replace_sysroot_result" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) func_append dlfiles " $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) func_append dlprefiles " $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - func_append deplibs " System.ltframework" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) - # Do not include libc due to us having libc/libc_r. - ;; - *-*-sco3.2v5* | *-*-sco5v6*) - # Causes problems with __ctype - ;; - *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) - # Compiler inserts libc in the correct place for threads to work - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test "$build_libtool_need_lc" = "yes"; then - func_append deplibs " -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behavior. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $opt_dry_run || $RM conftest.c - cat > conftest.c </dev/null` - $nocaseglob - else - potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` - fi - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null | - $GREP " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | - $SED -e 10q | - $EGREP "$file_magic_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $ECHO "*** with $libname but no candidates were found. (...for file magic test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a file magic. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method; shift - match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` - for a_deplib in $deplibs; do - case $a_deplib in - -l*) - func_stripname -l '' "$a_deplib" - name=$func_stripname_result - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - case " $predeps $postdeps " in - *" $a_deplib "*) - func_append newdeplibs " $a_deplib" - a_deplib="" - ;; - esac - fi - if test -n "$a_deplib" ; then - libname=`eval "\\$ECHO \"$libname_spec\""` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check above in file_magic test - if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ - $EGREP "$match_pattern_regex" > /dev/null; then - func_append newdeplibs " $a_deplib" - a_deplib="" - break 2 - fi - done - done - fi - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - $ECHO "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" - else - $ECHO "*** with $libname and none of the candidates passed a file format test" - $ECHO "*** using a regex pattern. Last file checked: $potlib" - fi - fi - ;; - *) - # Add a -L argument. - func_append newdeplibs " $a_deplib" - ;; - esac - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` - if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then - for i in $predeps $postdeps ; do - # can't use Xsed below, because $i might contain '/' - tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` - done - fi - case $tmp_deplibs in - *[!\ \ ]*) - echo - if test "X$deplibs_check_method" = "Xnone"; then - echo "*** Warning: inter-library dependencies are not supported in this platform." - else - echo "*** Warning: inter-library dependencies are not known to be supported." - fi - echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - ;; - esac - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library with the System framework - newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - echo - echo "*** Warning: libtool could not satisfy all declared inter-library" - $ECHO "*** dependencies of module $libname. Therefore, libtool will create" - echo "*** a static module, that should work as long as the dlopening" - echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - echo "*** The inter-library dependencies that have been dropped here will be" - echo "*** automatically added whenever a program is linked with this library" - echo "*** or is declared to -dlopen it." - - if test "$allow_undefined" = no; then - echo - echo "*** Since this library must not contain undefined symbols," - echo "*** because either the platform does not support them or" - echo "*** it was explicitly requested with -no-undefined," - echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - case $host in - *-*-darwin*) - newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - deplibs="$new_libs" - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - # Remove ${wl} instances when linking with ld. - # FIXME: should test the right _cmds variable. - case $archive_cmds in - *\$LD\ *) wl= ;; - esac - if test "$hardcode_into_libs" = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$opt_mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - func_replace_sysroot "$libdir" - libdir=$func_replace_sysroot_result - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append dep_rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_append perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval shared_ext=\"$shrext_cmds\" - eval library_names=\"$library_names_spec\" - set dummy $library_names - shift - realname="$1" - shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - if test -z "$dlname"; then - dlname=$soname - fi - - lib="$output_objdir/$realname" - linknames= - for link - do - func_append linknames " $link" - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` - test "X$libobjs" = "X " && libobjs= - - delfiles= - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" - export_symbols="$output_objdir/$libname.uexp" - func_append delfiles " $export_symbols" - fi - - orig_export_symbols= - case $host_os in - cygwin* | mingw* | cegcc*) - if test -n "$export_symbols" && test -z "$export_symbols_regex"; then - # exporting using user supplied symfile - if test "x`$SED 1q $export_symbols`" != xEXPORTS; then - # and it's NOT already a .def file. Must figure out - # which of the given symbols are data symbols and tag - # them as such. So, trigger use of export_symbols_cmds. - # export_symbols gets reassigned inside the "prepare - # the list of exported symbols" if statement, so the - # include_expsyms logic still works. - orig_export_symbols="$export_symbols" - export_symbols= - always_export_symbols=yes - fi - fi - ;; - esac - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $opt_dry_run || $RM $export_symbols - cmds=$export_symbols_cmds - save_ifs="$IFS"; IFS='~' - for cmd1 in $cmds; do - IFS="$save_ifs" - # Take the normal branch if the nm_file_list_spec branch - # doesn't work or if tool conversion is not needed. - case $nm_file_list_spec~$to_tool_file_cmd in - *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) - try_normal_branch=yes - eval cmd=\"$cmd1\" - func_len " $cmd" - len=$func_len_result - ;; - *) - try_normal_branch=no - ;; - esac - if test "$try_normal_branch" = yes \ - && { test "$len" -lt "$max_cmd_len" \ - || test "$max_cmd_len" -le -1; } - then - func_show_eval "$cmd" 'exit $?' - skipped_export=false - elif test -n "$nm_file_list_spec"; then - func_basename "$output" - output_la=$func_basename_result - save_libobjs=$libobjs - save_output=$output - output=${output_objdir}/${output_la}.nm - func_to_tool_file "$output" - libobjs=$nm_file_list_spec$func_to_tool_file_result - func_append delfiles " $output" - func_verbose "creating $NM input file list: $output" - for obj in $save_libobjs; do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > "$output" - eval cmd=\"$cmd1\" - func_show_eval "$cmd" 'exit $?' - output=$save_output - libobjs=$save_libobjs - skipped_export=false - else - # The command line is too long to execute in one step. - func_verbose "using reloadable object file for export list..." - skipped_export=: - # Break out early, otherwise skipped_export may be - # set to false by a later but shorter cmd. - break - fi - done - IFS="$save_ifs" - if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - - tmp_deplibs= - for test_deplib in $deplibs; do - case " $convenience " in - *" $test_deplib "*) ;; - *) - func_append tmp_deplibs " $test_deplib" - ;; - esac - done - deplibs="$tmp_deplibs" - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec" && - test "$compiler_needs_object" = yes && - test -z "$libobjs"; then - # extract the archives, so we have objects to list. - # TODO: could optimize this to just extract one archive. - whole_archive_flag_spec= - fi - if test -n "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - else - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - func_append linker_flags " $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$opt_mode" = relink; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - eval test_cmds=\"$module_expsym_cmds\" - cmds=$module_expsym_cmds - else - eval test_cmds=\"$module_cmds\" - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval test_cmds=\"$archive_expsym_cmds\" - cmds=$archive_expsym_cmds - else - eval test_cmds=\"$archive_cmds\" - cmds=$archive_cmds - fi - fi - - if test "X$skipped_export" != "X:" && - func_len " $test_cmds" && - len=$func_len_result && - test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - : - else - # The command line is too long to link in one step, link piecewise - # or, if using GNU ld and skipped_export is not :, use a linker - # script. - - # Save the value of $output and $libobjs because we want to - # use them later. If we have whole_archive_flag_spec, we - # want to use save_libobjs as it was before - # whole_archive_flag_spec was expanded, because we can't - # assume the linker understands whole_archive_flag_spec. - # This may have to be revisited, in case too many - # convenience libraries get linked in and end up exceeding - # the spec. - if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then - save_libobjs=$libobjs - fi - save_output=$output - func_basename "$output" - output_la=$func_basename_result - - # Clear the reloadable object creation command queue and - # initialize k to one. - test_cmds= - concat_cmds= - objlist= - last_robj= - k=1 - - if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then - output=${output_objdir}/${output_la}.lnkscript - func_verbose "creating GNU ld script: $output" - echo 'INPUT (' > $output - for obj in $save_libobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - echo ')' >> $output - func_append delfiles " $output" - func_to_tool_file "$output" - output=$func_to_tool_file_result - elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then - output=${output_objdir}/${output_la}.lnk - func_verbose "creating linker input file list: $output" - : > $output - set x $save_libobjs - shift - firstobj= - if test "$compiler_needs_object" = yes; then - firstobj="$1 " - shift - fi - for obj - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" >> $output - done - func_append delfiles " $output" - func_to_tool_file "$output" - output=$firstobj\"$file_list_spec$func_to_tool_file_result\" - else - if test -n "$save_libobjs"; then - func_verbose "creating reloadable object files..." - output=$output_objdir/$output_la-${k}.$objext - eval test_cmds=\"$reload_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - - # Loop over the list of objects to be linked. - for obj in $save_libobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - if test "X$objlist" = X || - test "$len" -lt "$max_cmd_len"; then - func_append objlist " $obj" - else - # The command $test_cmds is almost too long, add a - # command to the queue. - if test "$k" -eq 1 ; then - # The first file doesn't have a previous command to add. - reload_objs=$objlist - eval concat_cmds=\"$reload_cmds\" - else - # All subsequent reloadable object files will link in - # the last one created. - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" - fi - last_robj=$output_objdir/$output_la-${k}.$objext - func_arith $k + 1 - k=$func_arith_result - output=$output_objdir/$output_la-${k}.$objext - objlist=" $obj" - func_len " $last_robj" - func_arith $len0 + $func_len_result - len=$func_arith_result - fi - done - # Handle the remaining objects by creating one last - # reloadable object file. All subsequent reloadable object - # files will link in the last one created. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - reload_objs="$objlist $last_robj" - eval concat_cmds=\"\${concat_cmds}$reload_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" - fi - func_append delfiles " $output" - - else - output= - fi - - if ${skipped_export-false}; then - func_verbose "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $opt_dry_run || $RM $export_symbols - libobjs=$output - # Append the command to create the export file. - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" - if test -n "$last_robj"; then - eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" - fi - fi - - test -n "$save_libobjs" && - func_verbose "creating a temporary reloadable object file: $output" - - # Loop through the commands generated above and execute them. - save_ifs="$IFS"; IFS='~' - for cmd in $concat_cmds; do - IFS="$save_ifs" - $opt_silent || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - if test -n "$export_symbols_regex" && ${skipped_export-false}; then - func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - func_show_eval '$MV "${export_symbols}T" "$export_symbols"' - fi - fi - - if ${skipped_export-false}; then - if test -n "$export_symbols" && test -n "$include_expsyms"; then - tmp_export_symbols="$export_symbols" - test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" - $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' - fi - - if test -n "$orig_export_symbols"; then - # The given exports_symbols file has to be filtered, so filter it. - func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" - # FIXME: $output_objdir/$libname.filter potentially contains lots of - # 's' commands which not all seds can handle. GNU sed should be fine - # though. Also, the filter scales superlinearly with the number of - # global variables. join(1) would be nice here, but unfortunately - # isn't a blessed tool. - $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter - func_append delfiles " $export_symbols $output_objdir/$libname.filter" - export_symbols=$output_objdir/$libname.def - $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols - fi - fi - - libobjs=$output - # Restore the value of output. - output=$save_output - - if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - test "X$libobjs" = "X " && libobjs= - fi - # Expand the library linking commands again to reset the - # value of $libobjs for piecewise linking. - - # Do each of the archive commands. - if test "$module" = yes && test -n "$module_cmds" ; then - if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then - cmds=$module_expsym_cmds - else - cmds=$module_cmds - fi - else - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - cmds=$archive_expsym_cmds - else - cmds=$archive_cmds - fi - fi - fi - - if test -n "$delfiles"; then - # Append the command to remove temporary files to $cmds. - eval cmds=\"\$cmds~\$RM $delfiles\" - fi - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append libobjs " $func_extract_archives_result" - test "X$libobjs" = "X " && libobjs= - fi - - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - eval cmd=\"$cmd\" - $opt_silent || { - func_quote_for_expand "$cmd" - eval "func_echo $func_quote_for_expand_result" - } - $opt_dry_run || eval "$cmd" || { - lt_exit=$? - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - ( cd "$output_objdir" && \ - $RM "${realname}T" && \ - $MV "${realname}U" "$realname" ) - fi - - exit $lt_exit - } - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$opt_mode" = relink; then - $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? - - if test -n "$convenience"; then - if test -z "$whole_archive_flag_spec"; then - func_show_eval '${RM}r "$gentop"' - fi - fi - - exit $EXIT_SUCCESS - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - func_warning "\`-dlopen' is ignored for objects" - fi - - case " $deplibs" in - *\ -l* | *\ -L*) - func_warning "\`-l' and \`-L' are ignored for objects" ;; - esac - - test -n "$rpath" && \ - func_warning "\`-rpath' is ignored for objects" - - test -n "$xrpath" && \ - func_warning "\`-R' is ignored for objects" - - test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for objects" - - test -n "$release" && \ - func_warning "\`-release' is ignored for objects" - - case $output in - *.lo) - test -n "$objs$old_deplibs" && \ - func_fatal_error "cannot build library object \`$output' from non-libtool objects" - - libobj=$output - func_lo2o "$libobj" - obj=$func_lo2o_result - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $opt_dry_run || $RM $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec and hope we can get by with - # turning comma into space.. - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" - reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` - else - gentop="$output_objdir/${obj}x" - func_append generated " $gentop" - - func_extract_archives $gentop $convenience - reload_conv_objs="$reload_objs $func_extract_archives_result" - fi - fi - - # If we're not building shared, we need to use non_pic_objs - test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - func_execute_cmds "$reload_cmds" 'exit $?' - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - # $show "echo timestamp > $libobj" - # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? - exit $EXIT_SUCCESS - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - func_execute_cmds "$reload_cmds" 'exit $?' - fi - - if test -n "$gentop"; then - func_show_eval '${RM}r "$gentop"' - fi - - exit $EXIT_SUCCESS - ;; - - prog) - case $host in - *cygwin*) func_stripname '' '.exe' "$output" - output=$func_stripname_result.exe;; - esac - test -n "$vinfo" && \ - func_warning "\`-version-info' is ignored for programs" - - test -n "$release" && \ - func_warning "\`-release' is ignored for programs" - - test "$preload" = yes \ - && test "$dlopen_support" = unknown \ - && test "$dlopen_self" = unknown \ - && test "$dlopen_self_static" = unknown && \ - func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` - ;; - esac - - case $host in - *-*-darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - # But is supposedly fixed on 10.4 or later (yay!). - if test "$tagname" = CXX ; then - case ${MACOSX_DEPLOYMENT_TARGET-10.0} in - 10.[0123]) - func_append compile_command " ${wl}-bind_at_load" - func_append finalize_command " ${wl}-bind_at_load" - ;; - esac - fi - # Time to change all our "foo.ltframework" stuff back to "-framework foo" - compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` - ;; - esac - - - # move library search paths that coincide with paths to not yet - # installed libraries to the beginning of the library search list - new_libs= - for path in $notinst_path; do - case " $new_libs " in - *" -L$path/$objdir "*) ;; - *) - case " $compile_deplibs " in - *" -L$path/$objdir "*) - func_append new_libs " -L$path/$objdir" ;; - esac - ;; - esac - done - for deplib in $compile_deplibs; do - case $deplib in - -L*) - case " $new_libs " in - *" $deplib "*) ;; - *) func_append new_libs " $deplib" ;; - esac - ;; - *) func_append new_libs " $deplib" ;; - esac - done - compile_deplibs="$new_libs" - - - func_append compile_command " $compile_deplibs" - func_append finalize_command " $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) func_append finalize_rpath " $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) func_append perm_rpath " $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) - testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` - case :$dllsearchpath: in - *":$libdir:"*) ;; - ::) dllsearchpath=$libdir;; - *) func_append dllsearchpath ":$libdir";; - esac - case :$dllsearchpath: in - *":$testbindir:"*) ;; - ::) dllsearchpath=$testbindir;; - *) func_append dllsearchpath ":$testbindir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - func_append rpath " $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) func_append finalize_perm_rpath " $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` - fi - - func_generate_dlsyms "$outputname" "@PROGRAM@" "no" - - # template prelinking step - if test -n "$prelink_cmds"; then - func_execute_cmds "$prelink_cmds" 'exit $?' - fi - - wrappers_required=yes - case $host in - *cegcc* | *mingw32ce*) - # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. - wrappers_required=no - ;; - *cygwin* | *mingw* ) - if test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - *) - if test "$need_relink" = no || test "$build_libtool_libs" != yes; then - wrappers_required=no - fi - ;; - esac - if test "$wrappers_required" = no; then - # Replace the output file specification. - compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - exit_status=0 - func_show_eval "$link_command" 'exit_status=$?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Delete the generated files. - if test -f "$output_objdir/${outputname}S.${objext}"; then - func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' - fi - - exit $exit_status - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - func_append rpath "$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - func_append rpath "$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $opt_dry_run || $RM $output - # Link the executable and exit - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - exit $EXIT_SUCCESS - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - func_warning "this platform does not like uninstalled shared libraries" - func_warning "\`$output' will be relinked during installation" - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname - - func_show_eval "$link_command" 'exit $?' - - if test -n "$postlink_cmds"; then - func_to_tool_file "$output_objdir/$outputname" - postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` - func_execute_cmds "$postlink_cmds" 'exit $?' - fi - - # Now create the wrapper script. - func_verbose "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - fi - - # Only actually do things if not in dry run mode. - $opt_dry_run || { - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) func_stripname '' '.exe' "$output" - output=$func_stripname_result ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) - exeext=.exe - func_stripname '' '.exe' "$outputname" - outputname=$func_stripname_result ;; - *) exeext= ;; - esac - case $host in - *cygwin* | *mingw* ) - func_dirname_and_basename "$output" "" "." - output_name=$func_basename_result - output_path=$func_dirname_result - cwrappersource="$output_path/$objdir/lt-$output_name.c" - cwrapper="$output_path/$output_name.exe" - $RM $cwrappersource $cwrapper - trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 - - func_emit_cwrapperexe_src > $cwrappersource - - # The wrapper executable is built using the $host compiler, - # because it contains $host paths and files. If cross- - # compiling, it, like the target executable, must be - # executed on the $host or under an emulation environment. - $opt_dry_run || { - $LTCC $LTCFLAGS -o $cwrapper $cwrappersource - $STRIP $cwrapper - } - - # Now, create the wrapper script for func_source use: - func_ltwrapper_scriptname $cwrapper - $RM $func_ltwrapper_scriptname_result - trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 - $opt_dry_run || { - # note: this script will not be executed, so do not chmod. - if test "x$build" = "x$host" ; then - $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result - else - func_emit_wrapper no > $func_ltwrapper_scriptname_result - fi - } - ;; - * ) - $RM $output - trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 - - func_emit_wrapper no > $output - chmod +x $output - ;; - esac - } - exit $EXIT_SUCCESS - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save $symfileobj" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$old_deplibs $non_pic_objects" - if test "$preload" = yes && test -f "$symfileobj"; then - func_append oldobjs " $symfileobj" - fi - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $addlibs - func_append oldobjs " $func_extract_archives_result" - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - cmds=$old_archive_from_new_cmds - else - - # Add any objects from preloaded convenience libraries - if test -n "$dlprefiles"; then - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - - func_extract_archives $gentop $dlprefiles - func_append oldobjs " $func_extract_archives_result" - fi - - # POSIX demands no paths to be encoded in archives. We have - # to avoid creating archives with duplicate basenames if we - # might have to extract them afterwards, e.g., when creating a - # static archive out of a convenience library, or when linking - # the entirety of a libtool archive into another (currently - # not supported by libtool). - if (for obj in $oldobjs - do - func_basename "$obj" - $ECHO "$func_basename_result" - done | sort | sort -uc >/dev/null 2>&1); then - : - else - echo "copying selected object files to avoid basename conflicts..." - gentop="$output_objdir/${outputname}x" - func_append generated " $gentop" - func_mkdir_p "$gentop" - save_oldobjs=$oldobjs - oldobjs= - counter=1 - for obj in $save_oldobjs - do - func_basename "$obj" - objbase="$func_basename_result" - case " $oldobjs " in - " ") oldobjs=$obj ;; - *[\ /]"$objbase "*) - while :; do - # Make sure we don't pick an alternate name that also - # overlaps. - newobj=lt$counter-$objbase - func_arith $counter + 1 - counter=$func_arith_result - case " $oldobjs " in - *[\ /]"$newobj "*) ;; - *) if test ! -f "$gentop/$newobj"; then break; fi ;; - esac - done - func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" - func_append oldobjs " $gentop/$newobj" - ;; - *) func_append oldobjs " $obj" ;; - esac - done - fi - func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 - tool_oldlib=$func_to_tool_file_result - eval cmds=\"$old_archive_cmds\" - - func_len " $cmds" - len=$func_len_result - if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then - cmds=$old_archive_cmds - elif test -n "$archiver_list_spec"; then - func_verbose "using command file archive linking..." - for obj in $oldobjs - do - func_to_tool_file "$obj" - $ECHO "$func_to_tool_file_result" - done > $output_objdir/$libname.libcmd - func_to_tool_file "$output_objdir/$libname.libcmd" - oldobjs=" $archiver_list_spec$func_to_tool_file_result" - cmds=$old_archive_cmds - else - # the command line is too long to link in one step, link in parts - func_verbose "using piecewise archive linking..." - save_RANLIB=$RANLIB - RANLIB=: - objlist= - concat_cmds= - save_oldobjs=$oldobjs - oldobjs= - # Is there a better way of finding the last object in the list? - for obj in $save_oldobjs - do - last_oldobj=$obj - done - eval test_cmds=\"$old_archive_cmds\" - func_len " $test_cmds" - len0=$func_len_result - len=$len0 - for obj in $save_oldobjs - do - func_len " $obj" - func_arith $len + $func_len_result - len=$func_arith_result - func_append objlist " $obj" - if test "$len" -lt "$max_cmd_len"; then - : - else - # the above command should be used before it gets too long - oldobjs=$objlist - if test "$obj" = "$last_oldobj" ; then - RANLIB=$save_RANLIB - fi - test -z "$concat_cmds" || concat_cmds=$concat_cmds~ - eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" - objlist= - len=$len0 - fi - done - RANLIB=$save_RANLIB - oldobjs=$objlist - if test "X$oldobjs" = "X" ; then - eval cmds=\"\$concat_cmds\" - else - eval cmds=\"\$concat_cmds~\$old_archive_cmds\" - fi - fi - fi - func_execute_cmds "$cmds" 'exit $?' - done - - test -n "$generated" && \ - func_show_eval "${RM}r$generated" - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - func_verbose "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - func_quote_for_eval "$var_value" - relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` - if test "$hardcode_automatic" = yes ; then - relink_command= - fi - - # Only create the output if not a dry run. - $opt_dry_run || { - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - func_basename "$deplib" - name="$func_basename_result" - func_resolve_sysroot "$deplib" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` - test -z "$libdir" && \ - func_fatal_error "\`$deplib' is not a valid libtool archive" - func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" - ;; - -L*) - func_stripname -L '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -L$func_replace_sysroot_result" - ;; - -R*) - func_stripname -R '' "$deplib" - func_replace_sysroot "$func_stripname_result" - func_append newdependency_libs " -R$func_replace_sysroot_result" - ;; - *) func_append newdependency_libs " $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - - for lib in $dlfiles; do - case $lib in - *.la) - func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" - func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" - ;; - *) func_append newdlfiles " $lib" ;; - esac - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - *.la) - # Only pass preopened files to the pseudo-archive (for - # eventual linking with the app. that links it) if we - # didn't already link the preopened objects directly into - # the library: - func_basename "$lib" - name="$func_basename_result" - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - test -z "$libdir" && \ - func_fatal_error "\`$lib' is not a valid libtool archive" - func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" - ;; - esac - done - dlprefiles="$newdlprefiles" - else - newdlfiles= - for lib in $dlfiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlfiles " $abs" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - case $lib in - [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; - *) abs=`pwd`"/$lib" ;; - esac - func_append newdlprefiles " $abs" - done - dlprefiles="$newdlprefiles" - fi - $RM $output - # place dlname in correct position for cygwin - # In fact, it would be nice if we could use this code for all target - # systems that can't hard-code library paths into their executables - # and that have no shared library path variable independent of PATH, - # but it turns out we can't easily determine that from inspecting - # libtool variables, so we have to hard-code the OSs to which it - # applies here; at the moment, that means platforms that use the PE - # object format with DLL files. See the long comment at the top of - # tests/bindir.at for full details. - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) - # If a -bindir argument was supplied, place the dll there. - if test "x$bindir" != x ; - then - func_relative_path "$install_libdir" "$bindir" - tdlname=$func_relative_path_result$dlname - else - # Otherwise fall back on heuristic. - tdlname=../bin/$dlname - fi - ;; - esac - $ECHO > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Linker flags that can not go in dependency_libs. -inherited_linker_flags='$new_inherited_linker_flags' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Names of additional weak libraries provided by this library -weak_library_names='$weak_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Should we warn about portability when linking against -modules? -shouldnotlink=$module - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test "$need_relink" = yes; then - $ECHO >> $output "\ -relink_command=\"$relink_command\"" - fi - done - } - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' - ;; - esac - exit $EXIT_SUCCESS -} - -{ test "$opt_mode" = link || test "$opt_mode" = relink; } && - func_mode_link ${1+"$@"} - - -# func_mode_uninstall arg... -func_mode_uninstall () -{ - $opt_debug - RM="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) func_append RM " $arg"; rmforce=yes ;; - -*) func_append RM " $arg" ;; - *) func_append files " $arg" ;; - esac - done - - test -z "$RM" && \ - func_fatal_help "you must specify an RM program" - - rmdirs= - - for file in $files; do - func_dirname "$file" "" "." - dir="$func_dirname_result" - if test "X$dir" = X.; then - odir="$objdir" - else - odir="$dir/$objdir" - fi - func_basename "$file" - name="$func_basename_result" - test "$opt_mode" = uninstall && odir="$dir" - - # Remember odir for removal later, being careful to avoid duplicates - if test "$opt_mode" = clean; then - case " $rmdirs " in - *" $odir "*) ;; - *) func_append rmdirs " $odir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if { test -L "$file"; } >/dev/null 2>&1 || - { test -h "$file"; } >/dev/null 2>&1 || - test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if func_lalib_p "$file"; then - func_source $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - func_append rmfiles " $odir/$n" - done - test -n "$old_library" && func_append rmfiles " $odir/$old_library" - - case "$opt_mode" in - clean) - case " $library_names " in - *" $dlname "*) ;; - *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; - esac - test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" - ;; - uninstall) - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' - fi - # FIXME: should reinstall the best remaining shared library. - ;; - esac - fi - ;; - - *.lo) - # Possibly a libtool object, so verify it. - if func_lalib_p "$file"; then - - # Read the .lo file - func_source $dir/$name - - # Add PIC object to the list of files to remove. - if test -n "$pic_object" && - test "$pic_object" != none; then - func_append rmfiles " $dir/$pic_object" - fi - - # Add non-PIC object to the list of files to remove. - if test -n "$non_pic_object" && - test "$non_pic_object" != none; then - func_append rmfiles " $dir/$non_pic_object" - fi - fi - ;; - - *) - if test "$opt_mode" = clean ; then - noexename=$name - case $file in - *.exe) - func_stripname '' '.exe' "$file" - file=$func_stripname_result - func_stripname '' '.exe' "$name" - noexename=$func_stripname_result - # $file with .exe has already been added to rmfiles, - # add $file without .exe - func_append rmfiles " $file" - ;; - esac - # Do a test to see if this is a libtool program. - if func_ltwrapper_p "$file"; then - if func_ltwrapper_executable_p "$file"; then - func_ltwrapper_scriptname "$file" - relink_command= - func_source $func_ltwrapper_scriptname_result - func_append rmfiles " $func_ltwrapper_scriptname_result" - else - relink_command= - func_source $dir/$noexename - fi - - # note $name still contains .exe if it was in $file originally - # as does the version of $file that was added into $rmfiles - func_append rmfiles " $odir/$name $odir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - func_append rmfiles " $odir/lt-$name" - fi - if test "X$noexename" != "X$name" ; then - func_append rmfiles " $odir/lt-${noexename}.c" - fi - fi - fi - ;; - esac - func_show_eval "$RM $rmfiles" 'exit_status=1' - done - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - func_show_eval "rmdir $dir >/dev/null 2>&1" - fi - done - - exit $exit_status -} - -{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && - func_mode_uninstall ${1+"$@"} - -test -z "$opt_mode" && { - help="$generic_help" - func_fatal_help "you must specify a MODE" -} - -test -z "$exec_cmd" && \ - func_fatal_help "invalid operation mode \`$opt_mode'" - -if test -n "$exec_cmd"; then - eval exec "$exec_cmd" - exit $EXIT_FAILURE -fi - -exit $exit_status - - -# The TAGs below are defined such that we never get into a situation -# in which we disable both kinds of libraries. Given conflicting -# choices, we go for a static library, that is the most portable, -# since we can't tell whether shared libraries were disabled because -# the user asked for that or because the platform doesn't support -# them. This is particularly important on AIX, because we don't -# support having both static and shared libraries enabled at the same -# time on that platform, so we default to a shared-only configuration. -# If a disable-shared tag is given, we'll fallback to a static-only -# configuration. But we'll never go from static-only to shared-only. - -# ### BEGIN LIBTOOL TAG CONFIG: disable-shared -build_libtool_libs=no -build_old_libs=yes -# ### END LIBTOOL TAG CONFIG: disable-shared - -# ### BEGIN LIBTOOL TAG CONFIG: disable-static -build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` -# ### END LIBTOOL TAG CONFIG: disable-static - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: -# vi:sw=2 - diff --git a/build-aux/missing b/build-aux/missing deleted file mode 100755 index cdea514931..0000000000 --- a/build-aux/missing +++ /dev/null @@ -1,215 +0,0 @@ -#! /bin/sh -# Common wrapper for a few potentially missing GNU programs. - -scriptversion=2012-06-26.16; # UTC - -# Copyright (C) 1996-2013 Free Software Foundation, Inc. -# Originally written by Fran,cois Pinard , 1996. - -# 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 2, 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 to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -if test $# -eq 0; then - echo 1>&2 "Try '$0 --help' for more information" - exit 1 -fi - -case $1 in - - --is-lightweight) - # Used by our autoconf macros to check whether the available missing - # script is modern enough. - exit 0 - ;; - - --run) - # Back-compat with the calling convention used by older automake. - shift - ;; - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due -to PROGRAM being missing or too old. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - -Supported PROGRAM values: - aclocal autoconf autoheader autom4te automake makeinfo - bison yacc flex lex help2man - -Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and -'g' are ignored when checking the name. - -Send bug reports to ." - exit $? - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing $scriptversion (GNU Automake)" - exit $? - ;; - - -*) - echo 1>&2 "$0: unknown '$1' option" - echo 1>&2 "Try '$0 --help' for more information" - exit 1 - ;; - -esac - -# Run the given program, remember its exit status. -"$@"; st=$? - -# If it succeeded, we are done. -test $st -eq 0 && exit 0 - -# Also exit now if we it failed (or wasn't found), and '--version' was -# passed; such an option is passed most likely to detect whether the -# program is present and works. -case $2 in --version|--help) exit $st;; esac - -# Exit code 63 means version mismatch. This often happens when the user -# tries to use an ancient version of a tool on a file that requires a -# minimum version. -if test $st -eq 63; then - msg="probably too old" -elif test $st -eq 127; then - # Program was missing. - msg="missing on your system" -else - # Program was found and executed, but failed. Give up. - exit $st -fi - -perl_URL=http://www.perl.org/ -flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software - -program_details () -{ - case $1 in - aclocal|automake) - echo "The '$1' program is part of the GNU Automake package:" - echo "<$gnu_software_URL/automake>" - echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/autoconf>" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - autoconf|autom4te|autoheader) - echo "The '$1' program is part of the GNU Autoconf package:" - echo "<$gnu_software_URL/autoconf/>" - echo "It also requires GNU m4 and Perl in order to run:" - echo "<$gnu_software_URL/m4/>" - echo "<$perl_URL>" - ;; - esac -} - -give_advice () -{ - # Normalize program name to check for. - normalized_program=`echo "$1" | sed ' - s/^gnu-//; t - s/^gnu//; t - s/^g//; t'` - - printf '%s\n' "'$1' is $msg." - - configure_deps="'configure.ac' or m4 files included by 'configure.ac'" - case $normalized_program in - autoconf*) - echo "You should only need it if you modified 'configure.ac'," - echo "or m4 files included by it." - program_details 'autoconf' - ;; - autoheader*) - echo "You should only need it if you modified 'acconfig.h' or" - echo "$configure_deps." - program_details 'autoheader' - ;; - automake*) - echo "You should only need it if you modified 'Makefile.am' or" - echo "$configure_deps." - program_details 'automake' - ;; - aclocal*) - echo "You should only need it if you modified 'acinclude.m4' or" - echo "$configure_deps." - program_details 'aclocal' - ;; - autom4te*) - echo "You might have modified some maintainer files that require" - echo "the 'automa4te' program to be rebuilt." - program_details 'autom4te' - ;; - bison*|yacc*) - echo "You should only need it if you modified a '.y' file." - echo "You may want to install the GNU Bison package:" - echo "<$gnu_software_URL/bison/>" - ;; - lex*|flex*) - echo "You should only need it if you modified a '.l' file." - echo "You may want to install the Fast Lexical Analyzer package:" - echo "<$flex_URL>" - ;; - help2man*) - echo "You should only need it if you modified a dependency" \ - "of a man page." - echo "You may want to install the GNU Help2man package:" - echo "<$gnu_software_URL/help2man/>" - ;; - makeinfo*) - echo "You should only need it if you modified a '.texi' file, or" - echo "any other file indirectly affecting the aspect of the manual." - echo "You might want to install the Texinfo package:" - echo "<$gnu_software_URL/texinfo/>" - echo "The spurious makeinfo call might also be the consequence of" - echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" - echo "want to install GNU make:" - echo "<$gnu_software_URL/make/>" - ;; - *) - echo "You might have modified some files without having the proper" - echo "tools for further handling them. Check the 'README' file, it" - echo "often tells you about the needed prerequisites for installing" - echo "this package. You may also peek at any GNU archive site, in" - echo "case some other package contains this missing '$1' program." - ;; - esac -} - -give_advice "$1" | sed -e '1s/^/WARNING: /' \ - -e '2,$s/^/ /' >&2 - -# Propagate the correct exit status (expected to be 127 for a program -# not found, 63 for a program that failed due to version mismatch). -exit $st - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/cmake/FindnetCDF.cmake b/cmake/FindnetCDF.cmake index 393c57549b..361095954e 100644 --- a/cmake/FindnetCDF.cmake +++ b/cmake/FindnetCDF.cmake @@ -32,6 +32,7 @@ if (NOT netCDF_ROOT AND EXISTS "${BOUT_USE_NETCDF}") set(netCDF_ROOT "${BOUT_USE_NETCDF}") endif() +enable_language(C) find_package(netCDF QUIET CONFIG) if (netCDF_FOUND) diff --git a/cmake/SetupBOUTThirdParty.cmake b/cmake/SetupBOUTThirdParty.cmake index 518f3b9e90..38d1a71155 100644 --- a/cmake/SetupBOUTThirdParty.cmake +++ b/cmake/SetupBOUTThirdParty.cmake @@ -272,6 +272,7 @@ option(BOUT_DOWNLOAD_SUNDIALS "Download and build SUNDIALS" OFF) cmake_dependent_option(BOUT_USE_SUNDIALS "Enable support for SUNDIALS time solvers" OFF "NOT BOUT_DOWNLOAD_SUNDIALS" ON) if (BOUT_USE_SUNDIALS) + enable_language(C) if (BOUT_DOWNLOAD_SUNDIALS) message(STATUS "Downloading and configuring SUNDIALS") include(FetchContent) @@ -293,7 +294,6 @@ if (BOUT_USE_SUNDIALS) 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}.") diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 849f10e85f..f2444e6bf6 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -30,7 +30,6 @@ add_subdirectory(invertable_operator) add_subdirectory(laplacexy/alfven-wave) add_subdirectory(laplacexy/laplace_perp) add_subdirectory(laplacexy/simple) -add_subdirectory(laplacexy/simple-hypre) add_subdirectory(monitor-newapi) add_subdirectory(orszag-tang) add_subdirectory(preconditioning/wave) diff --git a/examples/dalf3/dalf3.cxx b/examples/dalf3/dalf3.cxx index 493e8f5e45..46a9a4286d 100644 --- a/examples/dalf3/dalf3.cxx +++ b/examples/dalf3/dalf3.cxx @@ -300,7 +300,7 @@ class DALF3 : public PhysicsModel { // LaplaceXY for n=0 solve if (split_n0) { // Create an XY solver for n=0 component - laplacexy = std::make_unique(mesh); + laplacexy = LaplaceXY::create(mesh); phi2D = 0.0; // Starting guess } diff --git a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx index 8e84901806..4ff8e90dcb 100644 --- a/examples/elm-pb-outerloop/elm_pb_outerloop.cxx +++ b/examples/elm-pb-outerloop/elm_pb_outerloop.cxx @@ -28,33 +28,26 @@ /*******************************************************************************/ +#include "bout/build_defines.hxx" +#include "bout/options.hxx" #include #include #include +#include #include #include #include #include #include #include -#include -#include - -#include - -#include -#include #include +#include // Defines BOUT_FOR_RAJA #include #include +#include +#include -#include // Defines BOUT_FOR_RAJA - -#if BOUT_HAS_HYPRE -#include -#endif - -#include +#include CELL_LOC loc = CELL_CENTRE; @@ -91,6 +84,10 @@ BOUT_OVERRIDE_DEFAULT_OPTION("phi:bndry_target", "neumann"); BOUT_OVERRIDE_DEFAULT_OPTION("phi:bndry_xin", "none"); BOUT_OVERRIDE_DEFAULT_OPTION("phi:bndry_xout", "none"); +#if BOUT_HAS_HYPRE +BOUT_OVERRIDE_DEFAULT_OPTION("laplacexy:type", "hypre"); +#endif + /// 3-field ELM simulation class ELMpb : public PhysicsModel { private: @@ -242,11 +239,7 @@ class ELMpb : public PhysicsModel { bool split_n0; // Solve the n=0 component of potential -#if BOUT_HAS_HYPRE - std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) -#else std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) -#endif Field2D phi2D; // Axisymmetric phi @@ -567,13 +560,11 @@ class ELMpb : public PhysicsModel { split_n0 = options["split_n0"] .doc("Solve zonal (n=0) component of potential using LaplaceXY?") .withDefault(false); + if (split_n0) { // Create an XY solver for n=0 component -#if BOUT_HAS_HYPRE - laplacexy = bout::utils::make_unique(mesh); -#else - laplacexy = bout::utils::make_unique(mesh); -#endif + laplacexy = LaplaceXY::create(mesh); + // Set coefficients for Boussinesq solve laplacexy->setCoefs(1.0, 0.0); phi2D = 0.0; // Starting guess diff --git a/examples/elm-pb/elm_pb.cxx b/examples/elm-pb/elm_pb.cxx index d981796200..fe18a756ae 100644 --- a/examples/elm-pb/elm_pb.cxx +++ b/examples/elm-pb/elm_pb.cxx @@ -22,10 +22,6 @@ #include -#if BOUT_HAS_HYPRE -#include -#endif - #include CELL_LOC loc = CELL_CENTRE; @@ -36,6 +32,10 @@ BOUT_OVERRIDE_DEFAULT_OPTION("phi:bndry_target", "neumann"); BOUT_OVERRIDE_DEFAULT_OPTION("phi:bndry_xin", "none"); BOUT_OVERRIDE_DEFAULT_OPTION("phi:bndry_xout", "none"); +#if BOUT_HAS_HYPRE +BOUT_OVERRIDE_DEFAULT_OPTION("laplacexy:type", "hypre"); +#endif + /// 3-field ELM simulation class ELMpb : public PhysicsModel { private: @@ -188,11 +188,7 @@ class ELMpb : public PhysicsModel { bool split_n0; // Solve the n=0 component of potential -#if BOUT_HAS_HYPRE - std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) -#else std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) -#endif Field2D phi2D; // Axisymmetric phi @@ -525,11 +521,8 @@ class ELMpb : public PhysicsModel { .withDefault(false); if (split_n0) { // Create an XY solver for n=0 component -#if BOUT_HAS_HYPRE - laplacexy = bout::utils::make_unique(mesh); -#else - laplacexy = bout::utils::make_unique(mesh); -#endif + laplacexy = LaplaceXY::create(mesh); + // Set coefficients for Boussinesq solve laplacexy->setCoefs(1.0, 0.0); phi2D = 0.0; // Starting guess diff --git a/examples/laplacexy/alfven-wave/alfven.cxx b/examples/laplacexy/alfven-wave/alfven.cxx index a4248afcf7..031931c1c4 100644 --- a/examples/laplacexy/alfven-wave/alfven.cxx +++ b/examples/laplacexy/alfven-wave/alfven.cxx @@ -1,10 +1,11 @@ - #include #include #include #include #include +#include + /// Fundamental constants const BoutReal PI = 3.14159265; const BoutReal e0 = 8.854e-12; // Permittivity of free space @@ -32,7 +33,7 @@ class Alfven : public PhysicsModel { bool laplace_perp; // Use Laplace_perp or Delp2? bool split_n0; // Split solve into n=0 and n~=0? - LaplaceXY* laplacexy; // Laplacian solver in X-Y (n=0) + std::unique_ptr laplacexy{nullptr}; // Laplacian solver in X-Y (n=0) bool newXZsolver; std::unique_ptr phiSolver; // Old Laplacian in X-Z @@ -80,7 +81,7 @@ class Alfven : public PhysicsModel { if (split_n0) { // Create an XY solver for n=0 component - laplacexy = new LaplaceXY(mesh); + laplacexy = LaplaceXY::create(mesh); phi2D = 0.0; // Starting guess } diff --git a/examples/laplacexy/laplace_perp/square/BOUT.inp b/examples/laplacexy/laplace_perp/square/BOUT.inp index 95ecb7119f..38fb175d90 100644 --- a/examples/laplacexy/laplace_perp/square/BOUT.inp +++ b/examples/laplacexy/laplace_perp/square/BOUT.inp @@ -1,5 +1,5 @@ -input = sin(pi*x - y) +input_field = sin(pi*x - y) non_uniform = true # Include corrections to second derivatives diff --git a/examples/laplacexy/laplace_perp/test.cxx b/examples/laplacexy/laplace_perp/test.cxx index 1312b005da..e3d9528d45 100644 --- a/examples/laplacexy/laplace_perp/test.cxx +++ b/examples/laplacexy/laplace_perp/test.cxx @@ -1,4 +1,5 @@ #include +#include #include #include @@ -10,11 +11,15 @@ int main(int argc, char** argv) { BoutInitialise(argc, argv); /////////////////////////////////////// - bool calc_metric; - calc_metric = Options::root()["calc_metric"].withDefault(false); + const bool calc_metric = Options::root()["calc_metric"].withDefault(false); if (calc_metric) { // Read metric tensor - Field2D Rxy, Btxy, Bpxy, B0, hthe, I; + Field2D Rxy; + Field2D Btxy; + Field2D Bpxy; + Field2D B0; + Field2D hthe; + Field2D I; mesh->get(Rxy, "Rxy"); // m mesh->get(Btxy, "Btxy"); // T mesh->get(Bpxy, "Bpxy"); // T @@ -47,10 +52,11 @@ int main(int argc, char** argv) { /////////////////////////////////////// // Read an analytic input - Field2D input = FieldFactory::get()->create2D("input", Options::getRoot(), mesh); + const Field2D input = + FieldFactory::get()->create2D("input_field", Options::getRoot(), mesh); // Create a LaplaceXY solver - LaplaceXY* laplacexy = new LaplaceXY(mesh); + auto laplacexy = LaplaceXY::create(mesh); // Solve, using 0.0 as starting guess Field2D solved = laplacexy->solve(input, 0.0); diff --git a/examples/laplacexy/laplace_perp/torus/BOUT.inp b/examples/laplacexy/laplace_perp/torus/BOUT.inp index 365294174f..4109b44bab 100644 --- a/examples/laplacexy/laplace_perp/torus/BOUT.inp +++ b/examples/laplacexy/laplace_perp/torus/BOUT.inp @@ -1,5 +1,5 @@ -input = sin(pi*x - y) +input_field = sin(pi*x - y) calc_metric = true # Read Rxy, Bpxy etc and calculate metric non_uniform = true # Include corrections to second derivatives diff --git a/examples/laplacexy/simple-hypre/.gitignore b/examples/laplacexy/simple-hypre/.gitignore deleted file mode 100644 index eeede075f9..0000000000 --- a/examples/laplacexy/simple-hypre/.gitignore +++ /dev/null @@ -1 +0,0 @@ -test-laplacexy diff --git a/examples/laplacexy/simple-hypre/CMakeLists.txt b/examples/laplacexy/simple-hypre/CMakeLists.txt deleted file mode 100644 index 788ebb1776..0000000000 --- a/examples/laplacexy/simple-hypre/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.13) - -project(test_laplacexy_hypre LANGUAGES CXX C) - -if (NOT TARGET bout++::bout++) - find_package(bout++ REQUIRED) -endif() - -bout_add_example(test_laplacexy_hypre - SOURCES test-laplacexy-hypre.cxx - REQUIRES BOUT_HAS_HYPRE) - -if(BOUT_HAS_CUDA) - set_source_files_properties(test-laplacexy-hypre.cxx PROPERTIES LANGUAGE CUDA ) -endif() diff --git a/examples/laplacexy/simple-hypre/data/BOUT.inp b/examples/laplacexy/simple-hypre/data/BOUT.inp deleted file mode 100644 index 5da492168d..0000000000 --- a/examples/laplacexy/simple-hypre/data/BOUT.inp +++ /dev/null @@ -1,37 +0,0 @@ -# -# Simple test of the LaplaceXY solver. -# -# Inverts a given function (rhs), writing "rhs" and solution "x" to file -# - -[mesh] - -# Mesh sizes -nx = 20 -ny = 32 -nz = 1 - -# mesh spacing -dx = 1.0 -dy = 1.0 -dz = 1.0 - -[laplacexy] - -ksptype = gmres # Iterative solver type - not used with Hypre interface -pctype = jacobi # Preconditioner. "jacobi", "bjacobi" and "sor" usually good -# On one processor"lu" uses direct solver - -atol = 1e-12 # type: BoutReal, doc: Relative tolerance for Hypre solver -core_bndry_dirichlet = false # type: bool -hypre_print_level = 3 # type: int, doc: Verbosity for Hypre solver. Integer from 0 (silent) to 4 (most verbose). -#hypre_solver_type = gmres # type: HYPRE_SOLVER_TYPE, doc: Type of solver to use when solving Hypre system. Possible values are: gmres, bicgstab -hypre_solver_type = bicgstab # type: HYPRE_SOLVER_TYPE, doc: Type of solver to use when solving Hypre system. Possible values are: gmres, bicgstab -include_y_derivs = true # type: bool, doc: Include Y derivatives in operator to invert? -maxits = 2000 # type: int, doc: Maximum iterations for Hypre solver -print_timing = true # type: bool, doc: Print extra timing information for LaplaceXY2Hypre -rtol = 1e-07 # type: BoutReal, doc: Relative tolerance for Hypre solver -y_bndry_dirichlet = false # type: bool - -# Function to be inverted -rhs = sin(2*pi*x)*sin(y) diff --git a/examples/laplacexy/simple-hypre/test-laplacexy-hypre.cxx b/examples/laplacexy/simple-hypre/test-laplacexy-hypre.cxx deleted file mode 100644 index af2367e1a0..0000000000 --- a/examples/laplacexy/simple-hypre/test-laplacexy-hypre.cxx +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include - -int main(int argc, char** argv) { - BoutInitialise(argc, argv); - { - /// Create a LaplaceXY object - LaplaceXY2Hypre laplacexy(bout::globals::mesh); - - /// Generate rhs function - Field2D rhs = FieldFactory::get()->create2D("laplacexy:rhs", Options::getRoot(), - bout::globals::mesh); - - /// Solution - Field2D solution = 0.0; - - solution = laplacexy.solve(rhs, solution); - - Options dump; - dump["rhs"] = rhs; - dump["x"] = solution; - bout::writeDefaultOutputFile(dump); - } - BoutFinalise(); -#if BOUT_HAS_CUDA - cudaDeviceReset(); -#endif - return 0; -} diff --git a/examples/laplacexy/simple/CMakeLists.txt b/examples/laplacexy/simple/CMakeLists.txt index ec5e7d2492..7859a08259 100644 --- a/examples/laplacexy/simple/CMakeLists.txt +++ b/examples/laplacexy/simple/CMakeLists.txt @@ -6,4 +6,7 @@ if (NOT TARGET bout++::bout++) find_package(bout++ REQUIRED) endif() -bout_add_example(laplacexy-simple SOURCES test-laplacexy.cxx) +bout_add_example(laplacexy-simple + SOURCES test-laplacexy.cxx + DATA_DIRS data hypre +) diff --git a/examples/laplacexy/simple/README.md b/examples/laplacexy/simple/README.md index ce7cbebf00..491d00d4b3 100644 --- a/examples/laplacexy/simple/README.md +++ b/examples/laplacexy/simple/README.md @@ -8,7 +8,7 @@ and preconditioners. See the "ksptype" and "pctype" settings in BOUT.inp Run with - $ ./test-laplacexy -ksp_monitor + $ ./test-laplacexy -laplacexy:petsc:ksp_monitor which should print the KSP norms from PETSc: @@ -31,3 +31,8 @@ which should print the KSP norms from PETSc: 16 KSP Residual norm 4.309526296050e-01 17 KSP Residual norm 1.115269396077e-01 18 KSP Residual norm 4.334487475743e-13 + +HYPRE +----- + +Use the `hypre` directory to use the HYPRE preconditioner instead of PETSc. diff --git a/examples/laplacexy/simple/hypre/BOUT.inp b/examples/laplacexy/simple/hypre/BOUT.inp new file mode 100644 index 0000000000..338e902d4e --- /dev/null +++ b/examples/laplacexy/simple/hypre/BOUT.inp @@ -0,0 +1,23 @@ +# +# Simple test of the LaplaceXY solver using HYPRE +# +# Inverts a given function (rhs), writing "rhs" and solution "x" to file +# + +[mesh] + +# Mesh sizes +nx = 20 +ny = 32 +nz = 1 + +# mesh spacing +dx = 1.0 +dy = 1.0 +dz = 1.0 + +[laplacexy] +type = hypre + +# Function to be inverted +rhs = sin(2*pi*x)*sin(y) diff --git a/examples/laplacexy/simple/test-laplacexy.cxx b/examples/laplacexy/simple/test-laplacexy.cxx index c033eb68e3..49a93aafdb 100644 --- a/examples/laplacexy/simple/test-laplacexy.cxx +++ b/examples/laplacexy/simple/test-laplacexy.cxx @@ -7,20 +7,18 @@ int main(int argc, char** argv) { BoutInitialise(argc, argv); /// Create a LaplaceXY object - LaplaceXY laplacexy(bout::globals::mesh); + auto laplacexy = LaplaceXY::create(bout::globals::mesh); /// Generate rhs function Field2D rhs = FieldFactory::get()->create2D("laplacexy:rhs", Options::getRoot(), bout::globals::mesh); /// Solution - Field2D x = 0.0; - - x = laplacexy.solve(rhs, x); + Field2D result = laplacexy->solve(rhs, 0.0); Options dump; dump["rhs"] = rhs; - dump["x"] = x; + dump["result"] = result; bout::writeDefaultOutputFile(dump); BoutFinalise(); diff --git a/externalpackages/PVODE/makefile b/externalpackages/PVODE/makefile deleted file mode 100644 index 410470a320..0000000000 --- a/externalpackages/PVODE/makefile +++ /dev/null @@ -1,16 +0,0 @@ -# Makefile for example codes -# Works in the same way as the root Makefile - -TARGET?=all - -DIRS = source precon - -all: $(DIRS) - -.PHONY: $(DIRS) - -$(DIRS): - @$(MAKE) -s --no-print-directory TARGET=$(TARGET) -C $@ $(TARGET) - -clean:: - @for pp in $(DIRS); do echo " " $$pp cleaned; $(MAKE) --no-print-directory -C $$pp clean; done diff --git a/externalpackages/boutdata b/externalpackages/boutdata index e458cf0cf2..7164a89c16 160000 --- a/externalpackages/boutdata +++ b/externalpackages/boutdata @@ -1 +1 @@ -Subproject commit e458cf0cf2af6ff68db91da39ef3e15a7e9e6b3d +Subproject commit 7164a89c16dba1049d42e1715506b988c0af5926 diff --git a/externalpackages/fmt b/externalpackages/fmt index 2ac6c5ca8b..407c905e45 160000 --- a/externalpackages/fmt +++ b/externalpackages/fmt @@ -1 +1 @@ -Subproject commit 2ac6c5ca8b3dfbcb1cc5cf49a8cc121e3984559c +Subproject commit 407c905e45ad75fc29bf0f9bb7c5c2fd3475976f diff --git a/externalpackages/googletest b/externalpackages/googletest index 0953a17a42..244cec869d 160000 --- a/externalpackages/googletest +++ b/externalpackages/googletest @@ -1 +1 @@ -Subproject commit 0953a17a4281fc26831da647ad3fcd5e21e6473b +Subproject commit 244cec869d12e53378fa0efb610cd4c32a454ec8 diff --git a/include/boundary_factory.hxx b/include/boundary_factory.hxx deleted file mode 100644 index abbead8fc4..0000000000 --- a/include/boundary_factory.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "boundary_factory.hxx" has moved to "bout/boundary_factory.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/boundary_factory.hxx" diff --git a/include/boundary_op.hxx b/include/boundary_op.hxx deleted file mode 100644 index c96310f2d4..0000000000 --- a/include/boundary_op.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "boundary_op.hxx" has moved to "bout/boundary_op.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/boundary_op.hxx" diff --git a/include/boundary_region.hxx b/include/boundary_region.hxx deleted file mode 100644 index f487e88aeb..0000000000 --- a/include/boundary_region.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "boundary_region.hxx" has moved to "bout/boundary_region.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/boundary_region.hxx" diff --git a/include/boundary_standard.hxx b/include/boundary_standard.hxx deleted file mode 100644 index b7f17cf363..0000000000 --- a/include/boundary_standard.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "boundary_standard.hxx" has moved to "bout/boundary_standard.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/boundary_standard.hxx" diff --git a/include/bout.hxx b/include/bout.hxx deleted file mode 100644 index 926f035d2f..0000000000 --- a/include/bout.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "bout.hxx" has moved to "bout/bout.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/bout.hxx" diff --git a/include/bout/boundary_iterator.hxx b/include/bout/boundary_iterator.hxx index 601f6a8a28..728c2e1cb0 100644 --- a/include/bout/boundary_iterator.hxx +++ b/include/bout/boundary_iterator.hxx @@ -43,14 +43,45 @@ public: return 2 * f(0, ind()) - f(0, ind().yp(-by).xp(-bx)); } - BoutReal interpolate_sheath_o1(const Field3D& f) const { + BoutReal interpolate_sheath_o2(const Field3D& f) const { return (f[ind()] + ynext(f)) * 0.5; } + + BoutReal + interpolate_sheath_o2(const std::function& f) const { + return (f(0, ind()) + f(0, ind().yp(-by).xp(-bx))) * 0.5; + } + BoutReal extrapolate_sheath_o2(const std::function& f) const { return 0.5 * (3 * f(0, ind()) - f(0, ind().yp(-by).xp(-bx))); } + BoutReal extrapolate_sheath_free(const Field3D& f, SheathLimitMode mode) const { + const BoutReal fac = + bout::parallel_boundary_region::limitFreeScale(yprev(f), ythis(f), mode); + BoutReal val = ythis(f); + BoutReal next = mode == SheathLimitMode::linear_free ? val + fac : val * fac; + return 0.5 * (val + next); + } + + void set_free(Field3D& f, SheathLimitMode mode) const { + const BoutReal fac = + bout::parallel_boundary_region::limitFreeScale(yprev(f), ythis(f), mode); + BoutReal val = ythis(f); + if (mode == SheathLimitMode::linear_free) { + for (int i = 1; i <= localmesh->ystart; ++i) { + val += fac; + f[ind().yp(by * i).xp(bx * i)] = val; + } + } else { + for (int i = 1; i <= localmesh->ystart; ++i) { + val *= fac; + f[ind().yp(by * i).xp(bx * i)] = val; + } + } + } + void limitFree(Field3D& f) const { const BoutReal fac = bout::parallel_boundary_region::limitFreeScale(yprev(f), ythis(f)); @@ -61,6 +92,11 @@ public: } } + bool is_lower() const { + ASSERT2(bx == 0); + return by == -1; + } + void neumann_o1(Field3D& f, BoutReal grad) const { BoutReal val = ythis(f); for (int i = 1; i <= localmesh->ystart; ++i) { @@ -77,6 +113,12 @@ public: } } + void limit_at_least(Field3D& f, BoutReal value) const { + if (ynext(f) < value) { + ynext(f) = value; + } + } + BoutReal& ynext(Field3D& f) const { return f[ind().yp(by).xp(bx)]; } const BoutReal& ynext(const Field3D& f) const { return f[ind().yp(by).xp(bx)]; } BoutReal& yprev(Field3D& f) const { return f[ind().yp(-by).xp(-bx)]; } diff --git a/include/bout/coordinates.hxx b/include/bout/coordinates.hxx index d7c80ed8bc..8410b62765 100644 --- a/include/bout/coordinates.hxx +++ b/include/bout/coordinates.hxx @@ -159,7 +159,7 @@ public: const std::string& method = "DEFAULT", const std::string& region = "RGN_NOBNDRY"); - Field3D DDY(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT, + Field3D DDY(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT", const std::string& region = "RGN_NOBNDRY") const; @@ -171,7 +171,7 @@ public: FieldMetric Grad_par(const Field2D& var, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT"); - Field3D Grad_par(const Field3D& var, CELL_LOC outloc = CELL_DEFAULT, + Field3D Grad_par(const Field3DParallel& var, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT"); /// Advection along magnetic field V*b.Grad(f) @@ -179,7 +179,7 @@ public: CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT"); - Field3D Vpar_Grad_par(const Field3D& v, const Field3D& f, + Field3D Vpar_Grad_par(const Field3D& v, const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT"); @@ -187,14 +187,14 @@ public: FieldMetric Div_par(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT"); - Field3D Div_par(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT, + Field3D Div_par(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT"); // Second derivative along magnetic field FieldMetric Grad2_par2(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT"); - Field3D Grad2_par2(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT, + Field3D Grad2_par2(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT"); // Perpendicular Laplacian operator, using only X-Z derivatives // NOTE: This might be better bundled with the Laplacian inversion code @@ -206,13 +206,13 @@ public: // Full parallel Laplacian operator on scalar field // Laplace_par(f) = Div( b (b dot Grad(f)) ) FieldMetric Laplace_par(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT); - Field3D Laplace_par(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT); + Field3D Laplace_par(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT); // Full Laplacian operator on scalar field FieldMetric Laplace(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& dfdy_boundary_conditions = "free_o3", const std::string& dfdy_dy_region = ""); - Field3D Laplace(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT, + Field3D Laplace(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& dfdy_boundary_conditions = "free_o3", const std::string& dfdy_dy_region = ""); diff --git a/include/bout/deriv_store.hxx b/include/bout/deriv_store.hxx index 6dc44c76ad..4d555e42be 100644 --- a/include/bout/deriv_store.hxx +++ b/include/bout/deriv_store.hxx @@ -533,4 +533,13 @@ private: } }; +template +auto& getStore() { + if constexpr (std::is_same::value) { + return DerivativeStore::getInstance(); + } else { + return DerivativeStore::getInstance(); + } +} + #endif diff --git a/include/bout/derivs.hxx b/include/bout/derivs.hxx index 1c360bb9cd..a8d9279378 100644 --- a/include/bout/derivs.hxx +++ b/include/bout/derivs.hxx @@ -82,7 +82,7 @@ Coordinates::FieldMetric DDX(const Field2D& f, CELL_LOC outloc = CELL_DEFAULT, /// If not given, defaults to DIFF_DEFAULT /// @param[in] region What region is expected to be calculated /// If not given, defaults to RGN_NOBNDRY -Field3D DDY(const Field3D& f, CELL_LOC outloc = CELL_DEFAULT, +Field3D DDY(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT", const std::string& region = "RGN_NOBNDRY"); @@ -410,7 +410,7 @@ Coordinates::FieldMetric VDDX(const Field2D& v, const Field2D& f, /// If not given, defaults to DIFF_DEFAULT /// @param[in] region What region is expected to be calculated /// If not given, defaults to RGN_NOBNDRY -Field3D VDDY(const Field3D& v, const Field3D& f, CELL_LOC outloc = CELL_DEFAULT, +Field3D VDDY(const Field3D& v, const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT", const std::string& region = "RGN_NOBNDRY"); @@ -533,7 +533,7 @@ Coordinates::FieldMetric FDDX(const Field2D& v, const Field2D& f, /// If not given, defaults to DIFF_DEFAULT /// @param[in] region What region is expected to be calculated /// If not given, defaults to RGN_NOBNDRY -Field3D FDDY(const Field3D& v, const Field3D& f, CELL_LOC outloc = CELL_DEFAULT, +Field3D FDDY(const Field3D& v, const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT", const std::string& region = "RGN_NOBNDRY"); diff --git a/include/bout/difops.hxx b/include/bout/difops.hxx index 71053d454a..c2fdac195d 100644 --- a/include/bout/difops.hxx +++ b/include/bout/difops.hxx @@ -40,7 +40,9 @@ #include "bout/field3d.hxx" #include "bout/bout_types.hxx" -#include "bout/solver.hxx" +#include "bout/coordinates.hxx" + +class Solver; /*! * Parallel derivative (central differencing) in Y diff --git a/include/bout/field.hxx b/include/bout/field.hxx index 27835ecbd7..7786f78e37 100644 --- a/include/bout/field.hxx +++ b/include/bout/field.hxx @@ -185,8 +185,8 @@ inline bool areFieldsCompatible(const Field& field1, const Field& field2) { template inline T emptyFrom(const T& f) { static_assert(bout::utils::is_Field_v, "emptyFrom only works on Fields"); - return T(f.getMesh(), f.getLocation(), {f.getDirectionY(), f.getDirectionZ()}, - f.getRegionID()) + return T(f.getMesh(), f.getLocation(), + DirectionTypes{f.getDirectionY(), f.getDirectionZ()}, f.getRegionID()) .allocate(); } @@ -528,6 +528,7 @@ T pow(BoutReal lhs, const T& rhs, const std::string& rgn = "RGN_ALL") { * result for non-finite numbers * */ +class Field3DParallel; #ifdef FIELD_FUNC #error This macro has already been defined #else @@ -540,6 +541,12 @@ T pow(BoutReal lhs, const T& rhs, const std::string& rgn = "RGN_ALL") { /* Define and allocate the output result */ \ T result{emptyFrom(f)}; \ BOUT_FOR(d, result.getRegion(rgn)) { result[d] = func(f[d]); } \ + if constexpr (std::is_base_of_v) { \ + for (int i = 0; i < f.numberParallelSlices(); ++i) { \ + result.yup(i) = func(f.yup(i)); \ + result.ydown(i) = func(f.ydown(i)); \ + } \ + } \ result.name = std::string(#_name "(") + f.name + std::string(")"); \ checkData(result); \ return result; \ @@ -667,6 +674,8 @@ T copy(const T& f) { return result; } +class Field3DParallel; + /// Apply a floor value \p f to a field \p var. Any value lower than /// the floor is set to the floor. /// @@ -683,23 +692,22 @@ inline T floor(const T& var, BoutReal f, const std::string& rgn = "RGN_ALL") { result[d] = f; } } -#if BOUT_USE_FCI_AUTOMAGIC - if (var.isFci()) { - for (size_t i = 0; i < result.numberParallelSlices(); ++i) { - BOUT_FOR(d, result.yup(i).getRegion(rgn)) { - if (result.yup(i)[d] < f) { - result.yup(i)[d] = f; + if constexpr (std::is_same_v) { + if (var.hasParallelSlices()) { + for (size_t i = 0; i < result.numberParallelSlices(); ++i) { + BOUT_FOR(d, result.yup(i).getRegion(rgn)) { + if (result.yup(i)[d] < f) { + result.yup(i)[d] = f; + } } - } - BOUT_FOR(d, result.ydown(i).getRegion(rgn)) { - if (result.ydown(i)[d] < f) { - result.ydown(i)[d] = f; + BOUT_FOR(d, result.ydown(i).getRegion(rgn)) { + if (result.ydown(i)[d] < f) { + result.ydown(i)[d] = f; + } } } } - } else -#endif - { + } else { result.clearParallelSlices(); } return result; diff --git a/include/bout/field2d.hxx b/include/bout/field2d.hxx index 5eab330e8e..81147cc8e7 100644 --- a/include/bout/field2d.hxx +++ b/include/bout/field2d.hxx @@ -281,6 +281,8 @@ public: int size() const override { return nx * ny; } + Field2D& asField3DParallel() { return *this; } + private: /// Internal data array. Handles allocation/freeing of memory Array data; @@ -293,6 +295,10 @@ private: }; // Non-member overloaded operators +FieldPerp operator+(const Field2D& lhs, const FieldPerp& rhs); +FieldPerp operator-(const Field2D& lhs, const FieldPerp& rhs); +FieldPerp operator*(const Field2D& lhs, const FieldPerp& rhs); +FieldPerp operator/(const Field2D& lhs, const FieldPerp& rhs); Field2D operator+(const Field2D& lhs, const Field2D& rhs); Field2D operator-(const Field2D& lhs, const Field2D& rhs); diff --git a/include/bout/field3d.hxx b/include/bout/field3d.hxx index 0643efbe0a..1a9b24d7fa 100644 --- a/include/bout/field3d.hxx +++ b/include/bout/field3d.hxx @@ -34,10 +34,13 @@ class Field3D; #include "bout/fieldperp.hxx" #include "bout/region.hxx" +#include #include +#include #include class Mesh; +class Field3DParallel; /// Class for 3D X-Y-Z scalar fields /*! @@ -335,6 +338,7 @@ public: const Region& getValidRegionWithDefault(const std::string& region_name) const; void setRegion(const std::string& region_name) override; void resetRegion() override; + void resetRegionParallel(); void setRegion(size_t id) override; void setRegion(std::optional id) override; std::optional getRegionID() const override { return regionID; }; @@ -516,6 +520,7 @@ public: const std::string& condition) override; void applyParallelBoundary(const std::string& region, const std::string& condition, Field3D* f); + void applyParallelBoundaryWithDefault(const std::string& condition); friend void swap(Field3D& first, Field3D& second) noexcept; @@ -525,7 +530,10 @@ public: bool allowCalcParallelSlices{true}; -private: + inline Field3DParallel asField3DParallel(); + inline const Field3DParallel asField3DParallel() const; + +protected: /// Array sizes (from fieldmesh). These are valid only if fieldmesh is not null int nx{-1}, ny{-1}, nz{-1}; @@ -577,6 +585,31 @@ Field3D operator-(BoutReal lhs, const Field3D& rhs); Field3D operator*(BoutReal lhs, const Field3D& rhs); Field3D operator/(BoutReal lhs, const Field3D& rhs); +Field3DParallel operator+(const Field3D& lhs, const Field3DParallel& rhs); +Field3DParallel operator-(const Field3D& lhs, const Field3DParallel& rhs); +Field3DParallel operator*(const Field3D& lhs, const Field3DParallel& rhs); +Field3DParallel operator/(const Field3D& lhs, const Field3DParallel& rhs); + +Field3DParallel operator+(const Field3DParallel& lhs, const Field3D& rhs); +Field3DParallel operator-(const Field3DParallel& lhs, const Field3D& rhs); +Field3DParallel operator*(const Field3DParallel& lhs, const Field3D& rhs); +Field3DParallel operator/(const Field3DParallel& lhs, const Field3D& rhs); + +Field3DParallel operator+(const Field3DParallel& lhs, const Field3DParallel& rhs); +Field3DParallel operator-(const Field3DParallel& lhs, const Field3DParallel& rhs); +Field3DParallel operator*(const Field3DParallel& lhs, const Field3DParallel& rhs); +Field3DParallel operator/(const Field3DParallel& lhs, const Field3DParallel& rhs); + +Field3DParallel operator+(BoutReal lhs, const Field3DParallel& rhs); +Field3DParallel operator-(BoutReal lhs, const Field3DParallel& rhs); +Field3DParallel operator*(BoutReal lhs, const Field3DParallel& rhs); +Field3DParallel operator/(BoutReal lhs, const Field3DParallel& rhs); + +Field3DParallel operator+(const Field3DParallel& lhs, BoutReal rhs); +Field3DParallel operator-(const Field3DParallel& lhs, BoutReal rhs); +Field3DParallel operator*(const Field3DParallel& lhs, BoutReal rhs); +Field3DParallel operator/(const Field3DParallel& lhs, BoutReal rhs); + /*! * Unary minus. Returns the negative of given field, * iterates over whole domain including guard/boundary cells. @@ -699,4 +732,121 @@ inline Field3D copy(const Field3D& f) { return result; } +/// Field3DParallel is intended to behave like Field3D, but preserve parallel +/// Fields. +/// Operations on Field3D, like multiplication, exp and floor only work on the +/// "main" field, Field3DParallel will retain the parallel slices. +class Field3DParallel : public Field3D { +public: + template + explicit Field3DParallel(Types... args) : Field3D(std::move(args)...) { + ensureFieldAligned(); + } + Field3DParallel(const Field3D& f) : Field3D(std::move(f)) { ensureFieldAligned(); } + Field3DParallel(const Field2D& f) : Field3D(std::move(f)) { ensureFieldAligned(); } + // Explicitly needed, as DirectionTypes is sometimes constructed from a + // brace enclosed list + explicit Field3DParallel(Mesh* localmesh = nullptr, CELL_LOC location_in = CELL_CENTRE, + DirectionTypes directions_in = {YDirectionType::Standard, + ZDirectionType::Standard}, + std::optional regionID = {}) + : Field3D(localmesh, location_in, directions_in, regionID) { + splitParallelSlices(); + ensureFieldAligned(); + } + explicit Field3DParallel(Array data, Mesh* localmesh, + CELL_LOC location = CELL_CENTRE, + DirectionTypes directions_in = {YDirectionType::Standard, + ZDirectionType::Standard}) + : Field3D(std::move(data), localmesh, location, directions_in) { + ensureFieldAligned(); + } + explicit Field3DParallel(BoutReal, Mesh* mesh = nullptr); + Field3D& asField3D() { return *this; } + const Field3D& asField3D() const { return *this; } + + Field3DParallel& operator*=(const Field3D&); + Field3DParallel& operator/=(const Field3D&); + Field3DParallel& operator+=(const Field3D&); + Field3DParallel& operator-=(const Field3D&); + Field3DParallel& operator*=(const Field3DParallel&); + Field3DParallel& operator/=(const Field3DParallel&); + Field3DParallel& operator+=(const Field3DParallel&); + Field3DParallel& operator-=(const Field3DParallel&); + Field3DParallel& operator*=(BoutReal); + Field3DParallel& operator/=(BoutReal); + Field3DParallel& operator+=(BoutReal); + Field3DParallel& operator-=(BoutReal); + Field3DParallel& operator=(const Field3D& rhs) { + Field3D::operator=(rhs); + ensureFieldAligned(); + return *this; + } + Field3DParallel& operator=(Field3D&& rhs) { + Field3D::operator=(std::move(rhs)); + ensureFieldAligned(); + return *this; + } + Field3DParallel& operator=(BoutReal); + Field3DParallel& allocate(); + +private: + void ensureFieldAligned(); +}; + +Field3DParallel Field3D::asField3DParallel() { return Field3DParallel(*this); } +const Field3DParallel Field3D::asField3DParallel() const { + return Field3DParallel(*this); +} + +inline Field3D operator+(const Field2D& lhs, const Field3DParallel& rhs) { + return lhs + rhs.asField3D(); +} +inline Field3D operator-(const Field2D& lhs, const Field3DParallel& rhs) { + return lhs + rhs.asField3D(); +} +inline Field3D operator*(const Field2D& lhs, const Field3DParallel& rhs) { + return lhs + rhs.asField3D(); +} +inline Field3D operator/(const Field2D& lhs, const Field3DParallel& rhs) { + return lhs + rhs.asField3D(); +} + +inline Field3D operator+(const Field3DParallel& lhs, const Field2D& rhs) { + return lhs.asField3D() + rhs; +} +inline Field3D operator-(const Field3DParallel& lhs, const Field2D& rhs) { + return lhs.asField3D() - rhs; +} +inline Field3D operator*(const Field3DParallel& lhs, const Field2D& rhs) { + return lhs.asField3D() * rhs; +} +inline Field3D operator/(const Field3DParallel& lhs, const Field2D& rhs) { + return lhs.asField3D() / rhs; +} + +inline Field3DParallel +filledFrom(const Field3DParallel& f, + std::function func) { + auto result{emptyFrom(f)}; + if (f.hasParallelSlices()) { + BOUT_FOR(i, result.getRegion("RGN_NOY")) { result[i] = func(0, i); } + + for (size_t i = 0; i < result.numberParallelSlices(); ++i) { + result.yup(i).allocate(); + BOUT_FOR(d, result.yup(i).getValidRegionWithDefault("RGN_INVALID")) { + result.yup(i)[d] = func(i + 1, d); + } + result.ydown(i).allocate(); + BOUT_FOR(d, result.ydown(i).getValidRegionWithDefault("RGN_INVALID")) { + result.ydown(i)[d] = func(-i - 1, d); + } + } + } else { + BOUT_FOR(i, result.getRegion("RGN_ALL")) { result[i] = func(0, i); } + } + + return result; +} + #endif /* BOUT_FIELD3D_H */ diff --git a/include/bout/fv_ops.hxx b/include/bout/fv_ops.hxx index 8a9baaf3e7..17658f4eba 100644 --- a/include/bout/fv_ops.hxx +++ b/include/bout/fv_ops.hxx @@ -193,11 +193,9 @@ template const Field3D Div_par(const Field3D& f_in, const Field3D& v_in, const Field3D& wave_speed_in, bool fixflux = true) { -#if BOUT_USE_FCI_AUTOMAGIC if (f_in.isFci()) { return ::Div_par(f_in, v_in); } -#endif ASSERT1_FIELDS_COMPATIBLE(f_in, v_in); ASSERT1_FIELDS_COMPATIBLE(f_in, wave_speed_in); diff --git a/include/bout/index_derivs.hxx b/include/bout/index_derivs.hxx index 456f98f8c2..d0f653d7d9 100644 --- a/include/bout/index_derivs.hxx +++ b/include/bout/index_derivs.hxx @@ -149,7 +149,7 @@ struct registerMethod { // removed and we can use nGuard directly in the template statement. const int nGuards = method.meta.nGuards; - auto& derivativeRegister = DerivativeStore::getInstance(); + auto& derivativeRegister = getStore(); switch (method.meta.derivType) { case (DERIV::Standard): diff --git a/include/bout/index_derivs_interface.hxx b/include/bout/index_derivs_interface.hxx index bc9a687b34..82489d3279 100644 --- a/include/bout/index_derivs_interface.hxx +++ b/include/bout/index_derivs_interface.hxx @@ -150,8 +150,8 @@ T standardDerivative(const T& f, CELL_LOC outloc, const std::string& method, } // Lookup the method - auto derivativeMethod = DerivativeStore::getInstance().getStandardDerivative( - method, direction, stagger, derivType); + auto derivativeMethod = + getStore().getStandardDerivative(method, direction, stagger, derivType); // Create the result field T result{emptyFrom(f).setLocation(outloc)}; @@ -177,6 +177,11 @@ T DDX(const T& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "D AUTO_TRACE(); return standardDerivative(f, outloc, method, region); } +inline Field3D DDX(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT, + const std::string& method = "DEFAULT", + const std::string& region = "RGN_NOBNDRY") { + return DDX(f.asField3D(), outloc, method, region); +} template T D2DX2(const T& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT", @@ -202,17 +207,12 @@ T DDY(const T& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "D AUTO_TRACE(); if (f.isFci()) { ASSERT1(f.getDirectionY() == YDirectionType::Standard); - T f_tmp = f; if (!f.hasParallelSlices()) { -#if BOUT_USE_FCI_AUTOMAGIC - f_tmp.calcParallelSlices(); -#else throw BoutException( "parallel slices needed for parallel derivatives. Make sure to communicate and " "apply parallel boundary conditions before calling derivative"); -#endif } - return standardDerivative(f_tmp, outloc, + return standardDerivative(f, outloc, method, region); } else { const bool is_unaligned = (f.getDirectionY() == YDirectionType::Standard); @@ -222,6 +222,11 @@ T DDY(const T& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "D return is_unaligned ? fromFieldAligned(result, region) : result; } } +inline Field3D DDY(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT, + const std::string& method = "DEFAULT", + const std::string& region = "RGN_NOBNDRY") { + return DDY(f.asField3D(), outloc, method, region); +} template T D2DY2(const T& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT", @@ -264,6 +269,11 @@ T DDZ(const T& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "D AUTO_TRACE(); return standardDerivative(f, outloc, method, region); } +inline Field3D DDZ(const Field3DParallel& f, CELL_LOC outloc = CELL_DEFAULT, + const std::string& method = "DEFAULT", + const std::string& region = "RGN_NOBNDRY") { + return DDZ(f.asField3D(), outloc, method, region); +} template T D2DZ2(const T& f, CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT", @@ -369,6 +379,11 @@ T VDDY(const T& vel, const T& f, CELL_LOC outloc = CELL_DEFAULT, return are_unaligned ? fromFieldAligned(result, region) : result; } } +inline Field3D VDDY(const Field3D& v, const Field3DParallel& f, + CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT", + const std::string& region = "RGN_NOBNDRY") { + return VDDY(v, f.asField3D(), outloc, method, region); +} template T FDDY(const T& vel, const T& f, CELL_LOC outloc = CELL_DEFAULT, @@ -393,6 +408,11 @@ T FDDY(const T& vel, const T& f, CELL_LOC outloc = CELL_DEFAULT, return are_unaligned ? fromFieldAligned(result, region) : result; } } +inline Field3D FDDY(const Field3D& v, const Field3DParallel& f, + CELL_LOC outloc = CELL_DEFAULT, const std::string& method = "DEFAULT", + const std::string& region = "RGN_NOBNDRY") { + return FDDY(v, f.asField3D(), outloc, method, region); +} ////////////// Z DERIVATIVE ///////////////// diff --git a/include/bout/invert/laplacexy.hxx b/include/bout/invert/laplacexy.hxx index 5a4dd46512..51605b9db5 100644 --- a/include/bout/invert/laplacexy.hxx +++ b/include/bout/invert/laplacexy.hxx @@ -1,18 +1,18 @@ /************************************************************************** - * Laplacian solver in 2D (X-Y) + * Perpendicular Laplacian inversion in X-Y * - * Equation solved is: + * Equation solved is: * * Div( A * Grad_perp(x) ) + B*x = b * * Intended for use in solving n = 0 component of potential * from inversion of vorticity equation - * + * ************************************************************************** - * Copyright 2015 B.Dudson + * Copyright 2015-2025 BOUT++ Team * * Contact: Ben Dudson, bd512@york.ac.uk - * + * * This file is part of BOUT++. * * BOUT++ is free software: you can redistribute it and/or modify @@ -30,196 +30,67 @@ * **************************************************************************/ -#ifndef BOUT_LAPLACE_XY_H -#define BOUT_LAPLACE_XY_H - -#include "bout/build_defines.hxx" +#ifndef BOUT_LAPLACEXY_H +#define BOUT_LAPLACEXY_H -#if !BOUT_HAS_PETSC -// If no PETSc - -#warning LaplaceXY requires PETSc. No LaplaceXY available +#include +#include +#include +#include -#include +#include -class Field2D; -class Mesh; +class LaplaceXY; class Options; class Solver; -/*! - * Create a dummy class so that code will compile - * without PETSc, but will throw an exception if - * LaplaceXY is used. - */ -class LaplaceXY { +class LaplaceXYFactory + : public Factory { public: - LaplaceXY(Mesh* UNUSED(m) = nullptr, Options* UNUSED(opt) = nullptr, - const CELL_LOC UNUSED(loc) = CELL_CENTRE) { - throw BoutException("LaplaceXY requires PETSc. No LaplaceXY available"); - } - void setCoefs(const Field2D& UNUSED(A), const Field2D& UNUSED(B)) {} - const Field2D solve(const Field2D& UNUSED(rhs), const Field2D& UNUSED(x0)) { - throw BoutException("LaplaceXY requires PETSc. No LaplaceXY available"); + static constexpr auto type_name = "LaplaceXY"; + static constexpr auto section_name = "laplacexy"; + static constexpr auto option_name = "type"; + static constexpr auto default_type = "petsc"; + + ReturnType create(Mesh* mesh = nullptr, Options* options = nullptr, + CELL_LOC loc = CELL_CENTRE) const { + return Factory::create(getType(options), mesh, optionsOrDefaultSection(options), loc); } - void savePerformance(Solver&, std::string) { - throw BoutException("LaplaceXY requires PETSc. No LaplaceXY available"); + ReturnType create(const std::string& type, Options* options) const { + return Factory::create(type, nullptr, options, CELL_CENTRE); } + + static void ensureRegistered(); }; -#else // BOUT_HAS_PETSC +template +using RegisterLaplaceXY = LaplaceXYFactory::RegisterInFactory; -#include "bout/solver.hxx" -#include "bout/utils.hxx" -#include -#include -#include - -class Options; -class Solver; +using RegisterUnavailableLaplaceXY = LaplaceXYFactory::RegisterUnavailableInFactory; class LaplaceXY { public: - /*! - * Constructor - */ - LaplaceXY(Mesh* m = nullptr, Options* opt = nullptr, const CELL_LOC loc = CELL_CENTRE); - /*! - * Destructor - */ - ~LaplaceXY(); - - /*! - * Set coefficients (A, B) in equation: - * Div( A * Grad_perp(x) ) + B*x = b - */ - void setCoefs(const Field2D& A, const Field2D& B); - - /*! - * Solve Laplacian in X-Y - * - * Inputs - * ====== - * - * rhs - The field to be inverted. This must be allocated - * and contain valid data. - * x0 - Initial guess at the solution. If this is unallocated - * then an initial guess of zero will be used. - * - * Returns - * ======= - * - * The solution as a Field2D. On failure an exception will be raised - * - */ - const Field2D solve(const Field2D& rhs, const Field2D& x0); - - /*! - * Preconditioner function - * This is called by PETSc via a static function. - * and should not be called by external users - */ - int precon(Vec x, Vec y); - - /*! - * If this method is called, save some performance monitoring information - */ - void savePerformance(Solver& solver, const std::string& name = ""); - -private: - PetscLib lib; ///< Requires PETSc library - Mat MatA; ///< Matrix to be inverted - Vec xs, bs; ///< Solution and RHS vectors - KSP ksp; ///< Krylov Subspace solver - PC pc; ///< Preconditioner + LaplaceXY() = default; + LaplaceXY(const LaplaceXY&) = default; + LaplaceXY(LaplaceXY&&) = delete; + LaplaceXY& operator=(const LaplaceXY&) = default; + LaplaceXY& operator=(LaplaceXY&&) = delete; + virtual ~LaplaceXY() = default; - Mesh* localmesh; ///< The mesh this operates on, provides metrics and communication + virtual void setCoefs(const Field2D& A, const Field2D& B) = 0; - /// default prefix for writing performance logging variables - std::string default_prefix; + virtual Field2D solve(const Field2D& b, const Field2D& x0) = 0; - // Preconditioner - int xstart, xend; - int nloc, nsys; - Matrix acoef, bcoef, ccoef, xvals, bvals; - std::unique_ptr> cr; ///< Tridiagonal solver - - // Use finite volume or finite difference discretization - bool finite_volume{true}; - - // Y derivatives - bool include_y_derivs; // Include Y derivative terms? - - // Boundary conditions - bool x_inner_dirichlet; // Dirichlet on inner X boundary? - bool x_outer_dirichlet; // Dirichlet on outer X boundary? - std::string y_bndry{"neumann"}; // Boundary condition for y-boundary - - // Location of the rhs and solution - CELL_LOC location; - - /*! - * Number of grid points on this processor - */ - int localSize(); - - /*! - * Return the communicator for XY - */ - MPI_Comm communicator(); - - /*! - * Return the global index of a local (x,y) coordinate - * including guard cells. - * Boundary cells have a global index of -1 - * - * To do this, a Field2D (indexXY) is used to store - * the index as a floating point number which is then rounded - * to an integer. Guard cells are filled by communication - * so no additional logic is needed in Mesh. - */ - int globalIndex(int x, int y); - Field2D indexXY; ///< Global index (integer stored as BoutReal) - - // Save performance information? - bool save_performance = false; - - // Running average of number of iterations taken for solve in each output timestep - BoutReal average_iterations = 0.; - - // Variable to store the final result of average_iterations, since output is - // written after all other monitors have been called, and average_iterations - // must be reset in the monitor - BoutReal output_average_iterations = 0.; - - // Running total of number of calls to the solver in each output timestep - int n_calls = 0; - - // Utility methods - void setPreallocationFiniteVolume(PetscInt* d_nnz, PetscInt* o_nnz); - void setPreallocationFiniteDifference(PetscInt* d_nnz, PetscInt* o_nnz); - void setMatrixElementsFiniteVolume(const Field2D& A, const Field2D& B); - void setMatrixElementsFiniteDifference(const Field2D& A, const Field2D& B); - void solveFiniteVolume(const Field2D& x0); - void solveFiniteDifference(const Field2D& x0); - - // Monitor class used to reset performance-monitoring variables for a new - // output timestep - friend class LaplaceXYMonitor; - class LaplaceXYMonitor : public Monitor { - public: - LaplaceXYMonitor(LaplaceXY& owner) : laplacexy(owner) {} - - int call(Solver* /*solver*/, BoutReal /*time*/, int /*iter*/, int /*nout*/) override; - void outputVars(Options& output_options, const std::string& time_dimension) override; - - private: - // LaplaceXY object that this monitor belongs to - LaplaceXY& laplacexy; - }; + static std::unique_ptr create(Mesh* m = nullptr, Options* opt = nullptr, + CELL_LOC loc = CELL_CENTRE) { + return LaplaceXYFactory::getInstance().create(m, opt, loc); + } - LaplaceXYMonitor monitor; +protected: + static const int INVERT_DC_GRAD = 1; + static const int INVERT_AC_GRAD = 2; // Use zero neumann (NOTE: AC is a misnomer) + static const int INVERT_SET = 16; // Set boundary to x0 value + static const int INVERT_RHS = 32; // Set boundary to b value }; -#endif // BOUT_HAS_PETSC -#endif // BOUT_LAPLACE_XY_H +#endif // BOUT_LAPLACEXY_H diff --git a/include/bout/invertable_operator.hxx b/include/bout/invertable_operator.hxx index fe139986be..9b9dbba41a 100644 --- a/include/bout/invertable_operator.hxx +++ b/include/bout/invertable_operator.hxx @@ -219,21 +219,18 @@ public: localmesh->LocalNy, localmesh->LocalNz, localmesh->maxregionblocksize); } } - if (localmesh->firstY() or localmesh->lastY()) { - for (int ix = localmesh->xstart; ix <= localmesh->xend; ix++) { - if (not localmesh->periodicY(ix)) { - if (localmesh->firstY()) { - nocorner3D += - Region(ix, ix, 0, localmesh->ystart - 1, 0, - localmesh->LocalNz - 1, localmesh->LocalNy, - localmesh->LocalNz, localmesh->maxregionblocksize); - } - if (localmesh->lastY()) { - nocorner3D += Region( - ix, ix, localmesh->LocalNy - localmesh->ystart, - localmesh->LocalNy - 1, 0, localmesh->LocalNz - 1, localmesh->LocalNy, - localmesh->LocalNz, localmesh->maxregionblocksize); - } + for (int ix = localmesh->xstart; ix <= localmesh->xend; ix++) { + if (not localmesh->periodicY(ix)) { + if (localmesh->firstY(ix)) { + nocorner3D += Region( + ix, ix, 0, localmesh->ystart - 1, 0, localmesh->LocalNz - 1, + localmesh->LocalNy, localmesh->LocalNz, localmesh->maxregionblocksize); + } + if (localmesh->lastY(ix)) { + nocorner3D += Region( + ix, ix, localmesh->LocalNy - localmesh->ystart, localmesh->LocalNy - 1, + 0, localmesh->LocalNz - 1, localmesh->LocalNy, localmesh->LocalNz, + localmesh->maxregionblocksize); } } } @@ -259,20 +256,17 @@ public: 0, 0, localmesh->LocalNy, 1, localmesh->maxregionblocksize); } } - if (localmesh->firstY() or localmesh->lastY()) { - for (int ix = localmesh->xstart; ix <= localmesh->xend; ix++) { - if (not localmesh->periodicY(ix)) { - if (localmesh->firstY()) { - nocorner2D += - Region(ix, ix, 0, localmesh->ystart - 1, 0, 0, - localmesh->LocalNy, 1, localmesh->maxregionblocksize); - } - if (localmesh->lastY()) { - nocorner2D += - Region(ix, ix, localmesh->LocalNy - localmesh->ystart, - localmesh->LocalNy - 1, 0, 0, localmesh->LocalNy, 1, - localmesh->maxregionblocksize); - } + for (int ix = localmesh->xstart; ix <= localmesh->xend; ix++) { + if (not localmesh->periodicY(ix)) { + if (localmesh->firstY(ix)) { + nocorner2D += + Region(ix, ix, 0, localmesh->ystart - 1, 0, 0, + localmesh->LocalNy, 1, localmesh->maxregionblocksize); + } + if (localmesh->lastY(ix)) { + nocorner2D += Region( + ix, ix, localmesh->LocalNy - localmesh->ystart, localmesh->LocalNy - 1, + 0, 0, localmesh->LocalNy, 1, localmesh->maxregionblocksize); } } } @@ -575,7 +569,7 @@ public: }; #endif // PETSC -}; // namespace inversion -}; // namespace bout +}; // namespace inversion +}; // namespace bout #endif // HEADER GUARD diff --git a/include/bout/options.hxx b/include/bout/options.hxx index e207c6b4d4..5b057fc3bb 100644 --- a/include/bout/options.hxx +++ b/include/bout/options.hxx @@ -205,6 +205,14 @@ public: bout::utils::variant, Matrix, Tensor>; + /// Methods to iterate over `Options` + auto begin() { return std::begin(children); } + auto end() { return std::end(children); } + auto begin() const { return std::begin(children); } + auto end() const { return std::end(children); } + auto cbegin() const { return std::cbegin(children); } + auto cend() const { return std::cend(children); } + /// A tree representation with leaves containing ValueType. /// Used to construct Options from initializer lists. /// diff --git a/include/bout/parallel_boundary_region.hxx b/include/bout/parallel_boundary_region.hxx index 849bb0ffe3..b31b6c8395 100644 --- a/include/bout/parallel_boundary_region.hxx +++ b/include/bout/parallel_boundary_region.hxx @@ -16,6 +16,8 @@ * */ +BOUT_ENUM_CLASS(SheathLimitMode, limit_free, exponential_free, linear_free); + namespace bout { namespace parallel_boundary_region { @@ -38,12 +40,52 @@ struct Indices { signed char valid; signed char offset; unsigned char abs_offset; + Indices(Ind3D index, RealPoint&& intersection, BoutReal length, signed char valid, + signed char offset, unsigned char abs_offset) + : index(index), intersection(intersection), length(length), valid(valid), + offset(offset), abs_offset(abs_offset){}; }; using IndicesVec = std::vector; using IndicesIter = IndicesVec::iterator; using IndicesIterConst = IndicesVec::const_iterator; +/// Limited free gradient of log of a quantity +/// This ensures that the guard cell values remain positive +/// while also ensuring that the quantity never increases +/// +/// fm fc | fp +/// ^ boundary +/// +/// exp( 2*log(fc) - log(fm) ) +inline BoutReal limitFreeScale(BoutReal fm, BoutReal fc, SheathLimitMode mode) { + if ((fm < fc) && (mode == SheathLimitMode::limit_free)) { + return fc; // Neumann rather than increasing into boundary + } + if (fm < 1e-10) { + return fc; // Low / no density condition + } + + BoutReal fp = 0; + switch (mode) { + case SheathLimitMode::limit_free: + case SheathLimitMode::exponential_free: + fp = SQ(fc) / fm; // Exponential + break; + case SheathLimitMode::linear_free: + fp = 2.0 * fc - fm; // Linear + break; + } + +#if CHECKLEVEL >= 2 + if (!std::isfinite(fp)) { + throw BoutException("SheathBoundary limitFree: {}, {} -> {}", fm, fc, fp); + } +#endif + + return fp; +} + inline BoutReal limitFreeScale(BoutReal fm, BoutReal fc) { if (fm < fc) { return 1; // Neumann rather than increasing into boundary @@ -103,7 +145,11 @@ public: return ythis(f) * (1 + length()) - yprev(f) * length(); } - inline BoutReal interpolate_sheath_o1(const Field3D& f) const { + inline BoutReal interpolate_sheath_o2(const Field3D& f) const { + return ythis(f) * (1 - length()) + ynext(f) * length(); + } + inline BoutReal + interpolate_sheath_o2(const std::function& f) const { return ythis(f) * (1 - length()) + ynext(f) * length(); } @@ -184,6 +230,16 @@ public: } } + void limit_at_least(Field3D& f, BoutReal value) const { + ITER() { + if (getAt(f, i) < value) { + getAt(f, i) = value; + } + } + } + + bool is_lower() const { return dir == -1; } + // 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. @@ -223,6 +279,31 @@ public: } } + BoutReal extrapolate_sheath_free(const Field3D& f, SheathLimitMode mode) const { + const auto fac = valid() > 0 ? limitFreeScale(yprev(f), ythis(f), mode) + : (mode == SheathLimitMode::linear_free ? 0 : 1); + auto val = ythis(f); + BoutReal next = mode == SheathLimitMode::linear_free ? val + fac : val * fac; + return val * length() + next * (1 - length()); + } + + void set_free(Field3D& f, SheathLimitMode mode) const { + const auto fac = valid() > 0 ? limitFreeScale(yprev(f), ythis(f), mode) + : (mode == SheathLimitMode::linear_free ? 0 : 1); + auto val = ythis(f); + if (mode == SheathLimitMode::linear_free) { + ITER() { + val += fac; + getAt(f, i) = val; + } + } else { + ITER() { + val *= fac; + getAt(f, i) = val; + } + } + } + void setAll(Field3D& f, const BoutReal val) const { for (int i = -localmesh->ystart; i <= localmesh->ystart; ++i) { f.ynext(i)[ind().yp(i)] = val; @@ -333,12 +414,9 @@ public: if (!bndry_points.empty() && bndry_points.back().index > ind) { is_sorted = false; } - bndry_points.push_back({ind, - {x, y, z}, - length, - valid, - offset, - static_cast(std::abs(offset))}); + bndry_points.emplace_back(ind, bout::parallel_boundary_region::RealPoint{x, y, z}, + length, valid, offset, + static_cast(std::abs(offset))); } void add_point(int ix, int iy, int iz, BoutReal x, BoutReal y, BoutReal z, BoutReal length, char valid, signed char offset) { diff --git a/include/bout/petsc_interface.hxx b/include/bout/petsc_interface.hxx index 90dd188d8a..3ae02f41a6 100644 --- a/include/bout/petsc_interface.hxx +++ b/include/bout/petsc_interface.hxx @@ -6,9 +6,9 @@ * up a linear system. * ************************************************************************** - * Copyright 2019 C. MacMackin + * Copyright 2019 - 2025 BOUT++ contributors * - * Contact: Ben Dudson, bd512@york.ac.uk + * Contact: Ben Dudson, dudson2@llnl.gov * * This file is part of BOUT++. * @@ -573,7 +573,7 @@ PetscVector operator*(const PetscMatrix& mat, const PetscVector& vec) { namespace bout { template constexpr auto cast_MatFDColoringFn(T func) { - return func; + return reinterpret_cast(func); // NOLINT(*-reinterpret-cast) } } // namespace bout #else diff --git a/include/bout/petsclib.hxx b/include/bout/petsclib.hxx index 83e57184aa..a1454b129e 100644 --- a/include/bout/petsclib.hxx +++ b/include/bout/petsclib.hxx @@ -22,9 +22,9 @@ * so it *must* be included before *any* PETSc header. * ************************************************************************** - * Copyright 2012 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu + * Copyright 2012 - 2025 BOUT++ contributors * - * Contact: Ben Dudson, bd512@york.ac.uk + * Contact: Ben Dudson, dudson2@llnl.gov * * This file is part of BOUT++. * @@ -60,6 +60,7 @@ class Options; #define PETSC_HAVE_BROKEN_RECURSIVE_MACRO #include // IWYU pragma: export +#include #include #include "bout/boutexception.hxx" @@ -113,6 +114,9 @@ public: /// was passed to the constructor. void setOptionsFromInputFile(SNES& snes); + /// Set options for a TS time integrator + void setOptionsFromInputFile(TS& ts); + /*! * Force cleanup. This will call PetscFinalize, printing a warning * if any instances of PetscLib still exist diff --git a/include/bout/utils.hxx b/include/bout/utils.hxx index e2ac814e53..ed2f7a2737 100644 --- a/include/bout/utils.hxx +++ b/include/bout/utils.hxx @@ -354,15 +354,14 @@ public: return data[(i1 * n2 + i2) * n3 + i3]; } - const T& operator[](Ind3D i) const { + const T& operator[](const 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) { + T& operator[](const Ind3D i) { // ny and nz are private :-( // ASSERT2(i.nz == n3); // ASSERT2(i.ny == n2); diff --git a/include/bout_types.hxx b/include/bout_types.hxx deleted file mode 100644 index e6048eb885..0000000000 --- a/include/bout_types.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "bout_types.hxx" has moved to "bout/bout_types.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/bout_types.hxx" diff --git a/include/boutcomm.hxx b/include/boutcomm.hxx deleted file mode 100644 index 256df49c4f..0000000000 --- a/include/boutcomm.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "boutcomm.hxx" has moved to "bout/boutcomm.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/boutcomm.hxx" diff --git a/include/boutexception.hxx b/include/boutexception.hxx deleted file mode 100644 index 9189babfb3..0000000000 --- a/include/boutexception.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "boutexception.hxx" has moved to "bout/boutexception.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/boutexception.hxx" diff --git a/include/cyclic_reduction.hxx b/include/cyclic_reduction.hxx deleted file mode 100644 index 3ff098b062..0000000000 --- a/include/cyclic_reduction.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "cyclic_reduction.hxx" has moved to "bout/cyclic_reduction.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/cyclic_reduction.hxx" diff --git a/include/dcomplex.hxx b/include/dcomplex.hxx deleted file mode 100644 index a91c5485bf..0000000000 --- a/include/dcomplex.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "dcomplex.hxx" has moved to "bout/dcomplex.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/dcomplex.hxx" diff --git a/include/derivs.hxx b/include/derivs.hxx deleted file mode 100644 index d0a6eb5831..0000000000 --- a/include/derivs.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "derivs.hxx" has moved to "bout/derivs.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/derivs.hxx" diff --git a/include/difops.hxx b/include/difops.hxx deleted file mode 100644 index a61d9712a9..0000000000 --- a/include/difops.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "difops.hxx" has moved to "bout/difops.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/difops.hxx" diff --git a/include/fft.hxx b/include/fft.hxx deleted file mode 100644 index d67b257388..0000000000 --- a/include/fft.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "fft.hxx" has moved to "bout/fft.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/fft.hxx" diff --git a/include/field.hxx b/include/field.hxx deleted file mode 100644 index a2fcb2464e..0000000000 --- a/include/field.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "field.hxx" has moved to "bout/field.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/field.hxx" diff --git a/include/field2d.hxx b/include/field2d.hxx deleted file mode 100644 index 3b148b3a50..0000000000 --- a/include/field2d.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "field2d.hxx" has moved to "bout/field2d.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/field2d.hxx" diff --git a/include/field3d.hxx b/include/field3d.hxx deleted file mode 100644 index 300cec057b..0000000000 --- a/include/field3d.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "field3d.hxx" has moved to "bout/field3d.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/field3d.hxx" diff --git a/include/field_data.hxx b/include/field_data.hxx deleted file mode 100644 index 90f5c96c40..0000000000 --- a/include/field_data.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "field_data.hxx" has moved to "bout/field_data.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/field_data.hxx" diff --git a/include/field_factory.hxx b/include/field_factory.hxx deleted file mode 100644 index c6302ee298..0000000000 --- a/include/field_factory.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "field_factory.hxx" has moved to "bout/field_factory.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/field_factory.hxx" diff --git a/include/fieldperp.hxx b/include/fieldperp.hxx deleted file mode 100644 index 1994e53060..0000000000 --- a/include/fieldperp.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "fieldperp.hxx" has moved to "bout/fieldperp.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/fieldperp.hxx" diff --git a/include/globals.hxx b/include/globals.hxx deleted file mode 100644 index f07488c10c..0000000000 --- a/include/globals.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "globals.hxx" has moved to "bout/globals.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/globals.hxx" diff --git a/include/gyro_average.hxx b/include/gyro_average.hxx deleted file mode 100644 index c0d454eb50..0000000000 --- a/include/gyro_average.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "gyro_average.hxx" has moved to "bout/gyro_average.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/gyro_average.hxx" diff --git a/include/initialprofiles.hxx b/include/initialprofiles.hxx deleted file mode 100644 index 7bc1595261..0000000000 --- a/include/initialprofiles.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "initialprofiles.hxx" has moved to "bout/initialprofiles.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/initialprofiles.hxx" diff --git a/include/interpolation.hxx b/include/interpolation.hxx deleted file mode 100644 index 80ad60b4e4..0000000000 --- a/include/interpolation.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "interpolation.hxx" has moved to "bout/interpolation.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/interpolation.hxx" diff --git a/include/interpolation_xz.hxx b/include/interpolation_xz.hxx deleted file mode 100644 index 8845e34b80..0000000000 --- a/include/interpolation_xz.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "interpolation_xz.hxx" has moved to "bout/interpolation_xz.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/interpolation_xz.hxx" diff --git a/include/interpolation_z.hxx b/include/interpolation_z.hxx deleted file mode 100644 index a88b486026..0000000000 --- a/include/interpolation_z.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "interpolation_z.hxx" has moved to "bout/interpolation_z.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/interpolation_z.hxx" diff --git a/include/invert_laplace.hxx b/include/invert_laplace.hxx deleted file mode 100644 index fbb04acaf1..0000000000 --- a/include/invert_laplace.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "invert_laplace.hxx" has moved to "bout/invert_laplace.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/invert_laplace.hxx" diff --git a/include/invert_parderiv.hxx b/include/invert_parderiv.hxx deleted file mode 100644 index 81a8ca4f49..0000000000 --- a/include/invert_parderiv.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "invert_parderiv.hxx" has moved to "bout/invert_parderiv.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/invert_parderiv.hxx" diff --git a/include/lapack_routines.hxx b/include/lapack_routines.hxx deleted file mode 100644 index 97fa2c6be9..0000000000 --- a/include/lapack_routines.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "lapack_routines.hxx" has moved to "bout/lapack_routines.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/lapack_routines.hxx" diff --git a/include/mask.hxx b/include/mask.hxx deleted file mode 100644 index cbeab65d85..0000000000 --- a/include/mask.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "mask.hxx" has moved to "bout/mask.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/mask.hxx" diff --git a/include/msg_stack.hxx b/include/msg_stack.hxx deleted file mode 100644 index 2503961748..0000000000 --- a/include/msg_stack.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "msg_stack.hxx" has moved to "bout/msg_stack.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/msg_stack.hxx" diff --git a/include/multiostream.hxx b/include/multiostream.hxx deleted file mode 100644 index 7e7101aad0..0000000000 --- a/include/multiostream.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "multiostream.hxx" has moved to "bout/multiostream.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/multiostream.hxx" diff --git a/include/options.hxx b/include/options.hxx deleted file mode 100644 index 4693422c13..0000000000 --- a/include/options.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "options.hxx" has moved to "bout/options.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/options.hxx" diff --git a/include/optionsreader.hxx b/include/optionsreader.hxx deleted file mode 100644 index 2c0f8344bf..0000000000 --- a/include/optionsreader.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "optionsreader.hxx" has moved to "bout/optionsreader.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/optionsreader.hxx" diff --git a/include/output.hxx b/include/output.hxx deleted file mode 100644 index 7eebcad478..0000000000 --- a/include/output.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "output.hxx" has moved to "bout/output.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/output.hxx" diff --git a/include/parallel_boundary_op.hxx b/include/parallel_boundary_op.hxx deleted file mode 100644 index e82a88d98f..0000000000 --- a/include/parallel_boundary_op.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "parallel_boundary_op.hxx" has moved to "bout/parallel_boundary_op.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/parallel_boundary_op.hxx" diff --git a/include/parallel_boundary_region.hxx b/include/parallel_boundary_region.hxx deleted file mode 100644 index dee2277007..0000000000 --- a/include/parallel_boundary_region.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "parallel_boundary_region.hxx" has moved to "bout/parallel_boundary_region.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/parallel_boundary_region.hxx" diff --git a/include/smoothing.hxx b/include/smoothing.hxx deleted file mode 100644 index b1a36adfb2..0000000000 --- a/include/smoothing.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "smoothing.hxx" has moved to "bout/smoothing.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/smoothing.hxx" diff --git a/include/sourcex.hxx b/include/sourcex.hxx deleted file mode 100644 index e09f3e89e4..0000000000 --- a/include/sourcex.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "sourcex.hxx" has moved to "bout/sourcex.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/sourcex.hxx" diff --git a/include/stencils.hxx b/include/stencils.hxx deleted file mode 100644 index fc877f3e1c..0000000000 --- a/include/stencils.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "stencils.hxx" has moved to "bout/stencils.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/stencils.hxx" diff --git a/include/unused.hxx b/include/unused.hxx deleted file mode 100644 index fa5ea7b6d1..0000000000 --- a/include/unused.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "unused.hxx" has moved to "bout/unused.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/unused.hxx" diff --git a/include/utils.hxx b/include/utils.hxx deleted file mode 100644 index d1a095e491..0000000000 --- a/include/utils.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "utils.hxx" has moved to "bout/utils.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/utils.hxx" diff --git a/include/vecops.hxx b/include/vecops.hxx deleted file mode 100644 index 1773418077..0000000000 --- a/include/vecops.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "vecops.hxx" has moved to "bout/vecops.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/vecops.hxx" diff --git a/include/vector2d.hxx b/include/vector2d.hxx deleted file mode 100644 index 6746d3f163..0000000000 --- a/include/vector2d.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "vector2d.hxx" has moved to "bout/vector2d.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/vector2d.hxx" diff --git a/include/vector3d.hxx b/include/vector3d.hxx deleted file mode 100644 index 747b6a75dd..0000000000 --- a/include/vector3d.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "vector3d.hxx" has moved to "bout/vector3d.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/vector3d.hxx" diff --git a/include/where.hxx b/include/where.hxx deleted file mode 100644 index e5b2bd9d30..0000000000 --- a/include/where.hxx +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -// BOUT++ header shim -#warning Header "where.hxx" has moved to "bout/where.hxx". Run `bin/bout-v5-header-upgrader.py` to fix -#include "bout/where.hxx" diff --git a/locale/de/libbout.po b/locale/de/libbout.po index 0e0773b5db..242beb45ca 100644 --- a/locale/de/libbout.po +++ b/locale/de/libbout.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: BOUT++ 4.2.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-09-12 09:17+0100\n" +"POT-Creation-Date: 2025-08-13 23:37+0100\n" "PO-Revision-Date: 2019-02-06 17:32+0000\n" "Last-Translator: David \n" "Language-Team: German\n" @@ -18,7 +18,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.2.1\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:191 +#: ../src/mesh/impls/bout/boutmesh.cxx:182 #, fuzzy, c++-format msgid "" "\t -> Core region jyseps2_1-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " @@ -27,7 +27,7 @@ msgstr "" "\t -> `Core` Region iyseps2_1-iyseps1_1 ({:d}-{:d} = {:d}) muss ein " "Vielfaches von MYSUB ({:d}) sein\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:224 +#: ../src/mesh/impls/bout/boutmesh.cxx:215 #, fuzzy, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " @@ -36,7 +36,7 @@ msgstr "" "\t -> `Core` Region jyseps2_2-jyseps1_1 ({:d}-{:d} = {:d}) muss ein " "Vielfaches von MYSUB ({:d}) sein\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:199 +#: ../src/mesh/impls/bout/boutmesh.cxx:190 #, fuzzy, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_2 ({:d}-{:d} = {:d}) must be a multiple " @@ -45,11 +45,11 @@ msgstr "" "\t -> `Core` Region jyseps2_2-jyseps1_2 ({:d}-{:d} = {:d}) muss ein " "Vielfaches von MYSUB ({:d}) sein\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:309 +#: ../src/mesh/impls/bout/boutmesh.cxx:300 msgid "\t -> Good value\n" msgstr "\t -> Wert OK\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:180 +#: ../src/mesh/impls/bout/boutmesh.cxx:171 #, fuzzy, c++-format msgid "" "\t -> Leg region jyseps1_1+1 ({:d}) must be a multiple of MYSUB ({:d})\n" @@ -57,7 +57,7 @@ msgstr "" "\t -> `Leg` Region jyseps1_1+1 ({:d}) muss ein Vielfaches von MYSUB ({:d}) " "sein\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:215 +#: ../src/mesh/impls/bout/boutmesh.cxx:206 #, fuzzy, c++-format msgid "" "\t -> leg region jyseps1_2-ny_inner+1 ({:d}-{:d}+1 = {:d}) must be a " @@ -66,7 +66,7 @@ msgstr "" "\t -> `Leg` Region jyseps1_2-ny_inner+1 ({:d}-{:d}+1 = {:d}) muss ein " "Vielfaches von MYSUB ({:d}) sein\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:232 +#: ../src/mesh/impls/bout/boutmesh.cxx:223 #, fuzzy, c++-format msgid "" "\t -> leg region ny-jyseps2_2-1 ({:d}-{:d}-1 = {:d}) must be a multiple of " @@ -75,7 +75,7 @@ msgstr "" "\t -> `Leg` Region ny-jyseps2_2-1 ({:d}-{:d}-1 = {:d}) muss ein Vielfaches " "von MYSUB ({:d}) sein\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:208 +#: ../src/mesh/impls/bout/boutmesh.cxx:199 #, fuzzy, c++-format msgid "" "\t -> leg region ny_inner-jyseps2_1-1 ({:d}-{:d}-1 = {:d}) must be a " @@ -84,12 +84,17 @@ msgstr "" "\t -> `Leg` Region ny_inner-jyseps2_1-1 ({:d}-{:d}-1 = {:d}) muss ein " "Vielfaches von MYSUB ({:d}) sein\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:175 +#: ../src/mesh/impls/bout/boutmesh.cxx:166 #, fuzzy, c++-format msgid "\t -> ny/NYPE ({:d}/{:d} = {:d}) must be >= MYG ({:d})\n" msgstr "\t -> ny/NYPE ({:d}/{:d} = {:d}) muss >= MYG ({:d}) sein\n" #: ../src/bout++.cxx:575 +#, fuzzy, c++-format +msgid "\tADIOS2 support {}\n" +msgstr "\tNetCDF Unterstützung ist aktiviert\n" + +#: ../src/bout++.cxx:583 #, c++-format msgid "\tBacktrace in exceptions {}\n" msgstr "" @@ -98,28 +103,28 @@ msgstr "" #. Processors divide equally #. Mesh in X divides equally #. Mesh in Y divides equally -#: ../src/mesh/impls/bout/boutmesh.cxx:297 +#: ../src/mesh/impls/bout/boutmesh.cxx:288 #, fuzzy, c++-format msgid "\tCandidate value: {:d}\n" msgstr "\tzu überprüfender Wert: {:d}\n" -#: ../src/bout++.cxx:576 +#: ../src/bout++.cxx:584 #, c++-format msgid "\tColour in logs {}\n" msgstr "" -#: ../src/bout++.cxx:594 +#: ../src/bout++.cxx:599 msgid "\tCommand line options for this run : " msgstr "\tKommandozeilenoptionen für diese Ausführung: " #. The stringify is needed here as BOUT_FLAGS_STRING may already contain quoted strings #. which could cause problems (e.g. terminate strings). -#: ../src/bout++.cxx:590 +#: ../src/bout++.cxx:595 #, fuzzy, c++-format msgid "\tCompiled with flags : {:s}\n" msgstr "\tWurde kompiliert mit den Optionen : {:s}\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:324 +#: ../src/mesh/impls/bout/boutmesh.cxx:315 #, fuzzy, c++-format msgid "" "\tDomain split (NXPE={:d}, NYPE={:d}) into domains (localNx={:d}, " @@ -128,14 +133,14 @@ msgstr "" "\tDas Gebiet wird in NXPE={:d} mal NYPE={:d} Gebiete der Größe localNx={:d} " "mal localNy={:d} aufgeteilt\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:364 +#: ../src/mesh/impls/bout/boutmesh.cxx:357 #, fuzzy, c++-format msgid "\tERROR: Cannot split {:d} Y points equally between {:d} processors\n" msgstr "" "\tFEHLER: {:d} Punkte in der Y-Richtung können nicht gleichmässig zwischen " "{:d} Prozessen verteilt werden\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:372 +#: ../src/mesh/impls/bout/boutmesh.cxx:365 #, fuzzy, c++-format msgid "\tERROR: Cannot split {:d} Z points equally between {:d} processors\n" msgstr "" @@ -156,31 +161,31 @@ msgstr "" msgid "\tEmpty key or value in command line '{:s}'\n" msgstr "\tSchlüssel (Key) oder Wert nicht gesetzt in der Befehlszeile '{:s}'\n" -#: ../src/bout++.cxx:582 +#: ../src/bout++.cxx:587 #, c++-format msgid "\tExtra debug output {}\n" msgstr "" -#: ../src/bout++.cxx:561 +#: ../src/bout++.cxx:568 #, fuzzy, c++-format msgid "\tFFT support {}\n" msgstr "\tNetCDF Unterstützung ist aktiviert\n" -#: ../src/bout++.cxx:585 +#: ../src/bout++.cxx:590 #, c++-format msgid "\tField name tracking {}\n" msgstr "" -#: ../src/bout++.cxx:583 +#: ../src/bout++.cxx:588 #, c++-format msgid "\tFloating-point exceptions {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:440 +#: ../src/mesh/impls/bout/boutmesh.cxx:476 msgid "\tGrid size: " msgstr "\tGittergröße: " -#: ../src/mesh/impls/bout/boutmesh.cxx:463 +#: ../src/mesh/impls/bout/boutmesh.cxx:499 #, fuzzy msgid "\tGuard cells (x,y,z): " msgstr "\tGuardzellen (x,y): " @@ -194,17 +199,17 @@ msgstr "" "\tDer Schlüssel darf nicht ':' enthalten\n" "\tZeile: {:s}" -#: ../src/bout++.cxx:563 +#: ../src/bout++.cxx:570 #, c++-format msgid "\tLAPACK support {}\n" msgstr "" -#: ../src/bout++.cxx:586 +#: ../src/bout++.cxx:591 #, c++-format msgid "\tMessage stack {}\n" msgstr "" -#: ../src/bout++.cxx:560 +#: ../src/bout++.cxx:567 #, c++-format msgid "\tMetrics mode is {}\n" msgstr "" @@ -214,98 +219,94 @@ msgstr "" msgid "\tMultiple '=' in command-line argument '{:s}'\n" msgstr "\t'=' darf nicht mehrfach vorkommen: '{:s}'\n" -#: ../src/bout++.cxx:562 +#: ../src/bout++.cxx:569 #, c++-format msgid "\tNatural language support {}\n" msgstr "" -#: ../src/bout++.cxx:567 +#: ../src/bout++.cxx:574 #, fuzzy, c++-format msgid "\tNetCDF support {}{}\n" msgstr "\tNetCDF Unterstützung ist aktiviert\n" -#: ../src/bout++.cxx:577 +#: ../src/bout++.cxx:585 #, fuzzy, c++-format -msgid "\tOpenMP parallelisation {}" -msgstr "\tOpenMP Parallelisierung ist deaktiviert\n" +msgid "\tOpenMP parallelisation {}, using {} threads\n" +msgstr "\tOpenMP Parallelisierung mit {:d} Threads ist aktiviert\n" #. Mark the option as used #. Option not found -#: ../src/sys/options.cxx:311 ../src/sys/options.cxx:380 -#: ../src/sys/options.cxx:415 ../src/sys/options.cxx:457 -#: ../src/sys/options.cxx:717 ../src/sys/options.cxx:744 -#: ../src/sys/options.cxx:771 ../include/bout/options.hxx:516 -#: ../include/bout/options.hxx:549 ../include/bout/options.hxx:573 -#: ../include/bout/options.hxx:820 +#: ../include/bout/options.hxx:586 ../include/bout/options.hxx:619 +#: ../include/bout/options.hxx:643 ../include/bout/options.hxx:896 msgid "\tOption " msgstr "\tOption " -#: ../src/sys/options.cxx:447 +#: ../src/sys/options.cxx:369 #, fuzzy, c++-format -msgid "\tOption '{:s}': Boolean expected. Got '{:s}'\n" -msgstr "\tOption '{:s}': Boolscherwert erwartet, '{:s}' gefunden\n" +msgid "\tOption {} = {}" +msgstr "\tOption " #: ../src/sys/options/options_ini.cxx:70 #, fuzzy, c++-format msgid "\tOptions file '{:s}' not found\n" msgstr "\tDie Optionendatei '{:s}' konnte nicht gefunden werden\n" -#: ../src/bout++.cxx:568 +#: ../src/bout++.cxx:576 #, c++-format msgid "\tPETSc support {}\n" msgstr "" -#: ../src/bout++.cxx:571 +#: ../src/bout++.cxx:579 #, c++-format msgid "\tPVODE support {}\n" msgstr "" -#: ../src/bout++.cxx:557 +#: ../src/bout++.cxx:564 msgid "\tParallel NetCDF support disabled\n" msgstr "\tParallele-NetCDF Unterstützung ist deaktiviert\n" -#: ../src/bout++.cxx:555 +#: ../src/bout++.cxx:562 msgid "\tParallel NetCDF support enabled\n" msgstr "\tParllele-NetCDF Unterstützung ist aktiviert\n" -#: ../src/bout++.cxx:569 +#: ../src/bout++.cxx:577 #, c++-format msgid "\tPretty function name support {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:437 +#: ../src/mesh/impls/bout/boutmesh.cxx:473 msgid "\tRead nz from input grid file\n" msgstr "\tnz wird von der Griddatei gelesen\n" -#: ../src/mesh/mesh.cxx:238 +#: ../src/mesh/mesh.cxx:249 msgid "\tReading contravariant vector " msgstr "\tKontravariantevektoren werden gelesen " -#: ../src/mesh/mesh.cxx:231 ../src/mesh/mesh.cxx:252 +#: ../src/mesh/mesh.cxx:242 ../src/mesh/mesh.cxx:263 msgid "\tReading covariant vector " msgstr "\tKovariantevektoren werden gelesen " -#: ../src/bout++.cxx:548 +#: ../src/bout++.cxx:555 #, c++-format msgid "\tRuntime error checking {}" msgstr "" -#: ../src/bout++.cxx:573 +#: ../src/bout++.cxx:581 #, c++-format msgid "\tSLEPc support {}\n" msgstr "" -#: ../src/bout++.cxx:574 +#: ../src/bout++.cxx:582 #, c++-format msgid "\tSUNDIALS support {}\n" msgstr "" -#: ../src/bout++.cxx:572 +#: ../src/bout++.cxx:580 #, c++-format msgid "\tScore-P support {}\n" msgstr "" -#: ../src/bout++.cxx:584 +#: ../src/bout++.cxx:589 #, fuzzy, c++-format msgid "\tSignal handling support {}\n" msgstr "\tSignalverarbeitung ist deaktiviert\n" @@ -315,7 +316,7 @@ msgstr "\tSignalverarbeitung ist deaktiviert\n" msgid "\tUsing a timestep {:e}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:577 +#: ../src/mesh/impls/bout/boutmesh.cxx:613 msgid "\tdone\n" msgstr "\tfertig\n" @@ -325,7 +326,7 @@ msgid "" "\tSplit Runge-Kutta-Legendre and SSP-RK3 solver\n" msgstr "" -#: ../src/bout++.cxx:371 +#: ../src/bout++.cxx:378 #, fuzzy msgid "" "\n" @@ -345,7 +346,7 @@ msgstr "" " -v, --verbose\t\tWortreicherer Ausgabe\n" " -q, --quiet\t\tNur wichtigere Ausgaben anzeigen\n" -#: ../src/sys/expressionparser.cxx:302 +#: ../src/sys/expressionparser.cxx:341 #, c++-format msgid "" "\n" @@ -353,7 +354,7 @@ msgid "" " Did you mean '{0}'?" msgstr "" -#: ../src/solver/solver.cxx:580 +#: ../src/solver/solver.cxx:586 #, fuzzy, c++-format msgid "" "\n" @@ -362,7 +363,7 @@ msgstr "" "\n" "Simulation beendet um {:s}\n" -#: ../src/solver/solver.cxx:532 +#: ../src/solver/solver.cxx:540 #, fuzzy, c++-format msgid "" "\n" @@ -374,7 +375,7 @@ msgstr "" #. Raw string to help with the formatting of the message, and a #. separate variable so clang-format doesn't barf on the #. exception -#: ../src/sys/options.cxx:1102 +#: ../src/sys/options.cxx:1158 msgid "" "\n" "There were unused input options:\n" @@ -402,7 +403,7 @@ msgid "" "{}" msgstr "" -#: ../src/bout++.cxx:382 +#: ../src/bout++.cxx:389 #, c++-format msgid "" " --print-config\t\tPrint the compile-time configuration\n" @@ -435,60 +436,60 @@ msgid "" "model source (e.g. {:s}.cxx)\n" msgstr "" -#: ../src/bout++.cxx:379 +#: ../src/bout++.cxx:386 #, fuzzy msgid " -c, --color\t\t\tColor output using bout-log-color\n" msgstr " -c, --color\t\tFarbliche Ausgabe mit bout-log-color\n" -#: ../include/bout/options.hxx:823 +#: ../include/bout/options.hxx:899 #, fuzzy msgid ") overwritten with:" msgstr ") überschrieben mit {:s}" -#: ../src/bout++.cxx:550 +#: ../src/bout++.cxx:557 #, c++-format msgid ", level {}" msgstr "" -#: ../src/bout++.cxx:579 -#, c++-format -msgid ", using {} threads" -msgstr "" - #: ../tests/unit/src/test_bout++.cxx:352 msgid "4 of 8" msgstr "" -#: ../src/sys/options.cxx:868 +#: ../src/sys/options.cxx:895 msgid "All options used\n" msgstr "Alle genutzten Optionen\n" -#: ../src/bout++.cxx:528 +#: ../src/bout++.cxx:535 #, fuzzy, c++-format msgid "BOUT++ version {:s}\n" msgstr "BOUT++ Version {:s}\n" -#: ../src/bout++.cxx:143 +#: ../src/bout++.cxx:147 #, fuzzy msgid "Bad command line arguments:\n" msgstr "\t'=' darf nicht mehrfach vorkommen: '{:s}'\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:559 +#: ../src/sys/expressionparser.cxx:192 +#, c++-format +msgid "Boolean operator argument {:e} is not a bool" +msgstr "" + +#: ../src/mesh/impls/bout/boutmesh.cxx:595 msgid "Boundary regions in this processor: " msgstr "Randgebiete auf diesem Prozessor: " -#: ../src/mesh/impls/bout/boutmesh.cxx:355 +#: ../src/mesh/impls/bout/boutmesh.cxx:348 #, fuzzy, c++-format msgid "Cannot split {:d} X points equally between {:d} processors\n" msgstr "" "{:d} Punkte in der X-Richtung können nicht gleichmässig zwischen {:d} " "Prozessen verteilt werden\n" -#: ../src/bout++.cxx:818 +#: ../src/bout++.cxx:829 msgid "Check if a file exists, and exit if it does." msgstr "" -#: ../src/bout++.cxx:533 +#: ../src/bout++.cxx:540 #, fuzzy, c++-format msgid "" "Code compiled on {:s} at {:s}\n" @@ -501,7 +502,7 @@ msgstr "" msgid "Command line" msgstr "Befehlszeile" -#: ../src/bout++.cxx:544 ../tests/unit/src/test_bout++.cxx:358 +#: ../src/bout++.cxx:551 ../tests/unit/src/test_bout++.cxx:358 msgid "Compile-time options:\n" msgstr "Kompiliert mit:\n" @@ -510,16 +511,16 @@ msgstr "Kompiliert mit:\n" msgid "Compiled with flags" msgstr "\tWurde kompiliert mit den Optionen : {:s}\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:568 +#: ../src/mesh/impls/bout/boutmesh.cxx:604 msgid "Constructing default regions" msgstr "Standardregionen werden erstellt" -#: ../src/bout++.cxx:520 +#: ../src/bout++.cxx:527 #, fuzzy, c++-format msgid "Could not create PID file {:s}" msgstr "Die Ausgabedatei '{:s}' konnte nicht geöffnet werden\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:318 +#: ../src/mesh/impls/bout/boutmesh.cxx:309 msgid "" "Could not find a valid value for NXPE. Try a different number of processors." msgstr "" @@ -531,32 +532,32 @@ msgstr "" msgid "Could not open output file '{:s}'\n" msgstr "Die Ausgabedatei '{:s}' konnte nicht geöffnet werden\n" -#: ../src/bout++.cxx:652 +#: ../src/bout++.cxx:657 #, c++-format msgid "Could not open {:s}/{:s}.{:d} for writing" msgstr "" #. Error reading -#: ../src/mesh/mesh.cxx:532 +#: ../src/mesh/mesh.cxx:543 #, fuzzy, c++-format msgid "Could not read integer array '{:s}'\n" msgstr "Der Ganzzahlen-Array '{:s}' konnte nicht gelesen werden\n" #. Failed . Probably not important enough to stop the simulation -#: ../src/bout++.cxx:632 +#: ../src/bout++.cxx:637 msgid "Could not run bout-log-color. Make sure it is in your PATH\n" msgstr "" "Der Befehl 'bout-log-color' konnte nicht ausgeführt werden. Stellen Sie " "sicher, dass er sich in $PATH befindet.\n" -#: ../src/solver/solver.cxx:765 +#: ../src/solver/solver.cxx:772 #, fuzzy, c++-format msgid "Couldn't add Monitor: {:g} is not a multiple of {:g}!" msgstr "" "'Monitor' konnte nicht hinzugefügt werden: {:g} ist nicht ein Vielfaches von " "{:g}!" -#: ../src/sys/expressionparser.cxx:273 +#: ../src/sys/expressionparser.cxx:312 #, c++-format msgid "" "Couldn't find generator '{}'. BOUT++ expressions are now case-sensitive, so " @@ -565,73 +566,73 @@ msgid "" "{}" msgstr "" -#: ../src/mesh/mesh.cxx:568 +#: ../src/mesh/mesh.cxx:587 #, fuzzy, c++-format msgid "Couldn't find region {:s} in regionMap2D" msgstr "Die Region '{:s}' ist nicht in regionMap2D" -#: ../src/mesh/mesh.cxx:560 +#: ../src/mesh/mesh.cxx:571 ../src/mesh/mesh.cxx:579 #, fuzzy, c++-format msgid "Couldn't find region {:s} in regionMap3D" msgstr "Die Region '{:s}' ist nicht in regionMap3D" -#: ../src/mesh/mesh.cxx:576 +#: ../src/mesh/mesh.cxx:595 #, fuzzy, c++-format msgid "Couldn't find region {:s} in regionMapPerp" msgstr "Die Region '{:s}' ist nicht in regionMapPerp" #. Convert any exceptions to something a bit more useful -#: ../src/sys/options.cxx:336 +#: ../src/sys/options.cxx:361 #, fuzzy, c++-format msgid "Couldn't get {} from option {:s} = '{:s}': {}" msgstr "" "Die Option {:s} = '{:s}' konnte nicht als ganze Zahl interpretiert werden." -#: ../src/bout++.cxx:508 +#: ../src/bout++.cxx:515 #, fuzzy, c++-format msgid "DataDir \"{:s}\" does not exist or is not accessible\n" msgstr "Der Datenordner \"{:s}\" existiert nicht oder ist nicht lesbar\n" -#: ../src/bout++.cxx:505 +#: ../src/bout++.cxx:512 #, fuzzy, c++-format msgid "DataDir \"{:s}\" is not a directory\n" msgstr "" "\"{:s}\" soll als Datenordner verwendet werden, ist jedoch kein Ordner\n" -#: ../src/solver/solver.cxx:665 +#: ../src/solver/solver.cxx:671 msgid "ERROR: Solver is already initialised\n" msgstr "FEHLER: Der Integrator ist bereits initialisiert.\n" -#: ../src/bout++.cxx:209 +#: ../src/bout++.cxx:216 #, fuzzy, c++-format msgid "Error encountered during initialisation: {:s}\n" msgstr "Es wurde ein Fehler während der Initialisierung gefunden: {:s}\n" -#: ../src/bout++.cxx:744 +#: ../src/bout++.cxx:751 msgid "Error whilst writing settings" msgstr "Es wurde ein Fehler beim Schreiben der Einstellungsdatei gefunden" -#: ../src/mesh/impls/bout/boutmesh.cxx:332 +#: ../src/mesh/impls/bout/boutmesh.cxx:323 #, fuzzy, c++-format msgid "Error: nx must be greater than 2 times MXG (2 * {:d})" msgstr "Fehler: nx muss größer als 2 mal MXG sein (2 * {:d})" -#: ../src/solver/solver.cxx:512 +#: ../src/solver/solver.cxx:520 msgid "Failed to initialise solver-> Aborting\n" msgstr "" "Der Integrator konnte nicht initialisiert werden. Der Prozess wird " "abgebrochen\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:290 +#: ../src/mesh/impls/bout/boutmesh.cxx:281 #, fuzzy, c++-format msgid "Finding value for NXPE (ideal = {:f})\n" msgstr "Suche NXPE Wert (optimal = {:f})\n" -#: ../src/solver/solver.cxx:668 +#: ../src/solver/solver.cxx:674 msgid "Initialising solver\n" msgstr "initialisiere den Integrator\n" -#: ../src/bout++.cxx:494 +#: ../src/bout++.cxx:501 msgid "" "Input and output file for settings must be different.\n" "Provide -o to avoid this issue.\n" @@ -644,48 +645,48 @@ msgstr "" msgid "Invalid command line option '-' found - maybe check whitespace?" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:400 +#: ../src/mesh/impls/bout/boutmesh.cxx:436 msgid "Loading mesh" msgstr "Lade das Gitter" -#: ../src/mesh/impls/bout/boutmesh.cxx:415 +#: ../src/mesh/impls/bout/boutmesh.cxx:451 msgid "Mesh must contain nx" msgstr "Das Gitter muss nx enthalten" -#: ../src/mesh/impls/bout/boutmesh.cxx:419 +#: ../src/mesh/impls/bout/boutmesh.cxx:455 msgid "Mesh must contain ny" msgstr "Das Gitter muss ny enthalten" #. Not found -#: ../src/mesh/mesh.cxx:536 +#: ../src/mesh/mesh.cxx:547 #, fuzzy, c++-format msgid "Missing integer array {:s}\n" msgstr "Ganzzahlen-Array '{:s}' nicht gesetzt\n" -#: ../src/solver/solver.cxx:905 +#: ../src/solver/solver.cxx:911 #, fuzzy, c++-format msgid "Monitor signalled to quit (exception {})\n" msgstr "Beendigung durch Monitor\n" -#: ../src/solver/solver.cxx:883 +#: ../src/solver/solver.cxx:889 #, fuzzy, c++-format msgid "Monitor signalled to quit (return code {})" msgstr "Der Monitor signaliserte die Beendigung" -#: ../src/bout++.cxx:823 +#: ../src/bout++.cxx:834 msgid "Name of file whose existence triggers a stop" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:565 +#: ../src/mesh/impls/bout/boutmesh.cxx:601 msgid "No boundary regions in this processor" msgstr "Keine Randregionen auf diesem Prozessor" -#: ../src/mesh/impls/bout/boutmesh.cxx:550 +#: ../src/mesh/impls/bout/boutmesh.cxx:586 #, fuzzy msgid "No boundary regions; domain is periodic\n" msgstr "Keine Randregionen auf diesem Prozessor" -#: ../src/mesh/impls/bout/boutmesh.cxx:254 +#: ../src/mesh/impls/bout/boutmesh.cxx:245 #, fuzzy, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in x direction ({:d})\n" @@ -693,7 +694,7 @@ msgstr "" "Anzahl an Prozessoren ({:d}) nicht teilbar durch Anzahl in x Richtung " "({:d})\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:267 +#: ../src/mesh/impls/bout/boutmesh.cxx:258 #, fuzzy, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in y direction ({:d})\n" @@ -702,26 +703,26 @@ msgstr "" "({:d})\n" #. Less than 2 time-steps left -#: ../src/bout++.cxx:896 +#: ../src/bout++.cxx:908 #, fuzzy, c++-format msgid "Only {:e} seconds ({:.2f} steps) left. Quitting\n" msgstr "Nur noch {:e} Sekunden verfügbar. Abbruch\n" -#: ../src/sys/options.cxx:303 ../src/sys/options.cxx:345 -#: ../src/sys/options.cxx:393 ../src/sys/options.cxx:428 -#: ../src/sys/options.cxx:703 ../src/sys/options.cxx:730 -#: ../src/sys/options.cxx:757 +#: ../src/sys/options.cxx:382 ../src/sys/options.cxx:398 +#: ../src/sys/options.cxx:441 ../src/sys/options.cxx:471 +#: ../src/sys/options.cxx:745 ../src/sys/options.cxx:767 +#: ../src/sys/options.cxx:789 #, fuzzy, c++-format msgid "Option {:s} has no value" msgstr "Der Option '{:s}' wurde kein Wert zugewiesen" #. Doesn't exist -#: ../src/sys/options.cxx:159 +#: ../src/sys/options.cxx:172 #, fuzzy, c++-format msgid "Option {:s}:{:s} does not exist" msgstr "Die Option {:s}:{:s} exisitiert nicht" -#: ../include/bout/options.hxx:828 +#: ../include/bout/options.hxx:904 #, fuzzy, c++-format msgid "" "Options: Setting a value from same source ({:s}) to new value '{:s}' - old " @@ -730,12 +731,12 @@ msgstr "" "Optionen: Der Wert {2:s} wird mit dem Wert {1:s} gleichen Ursprungs ({0:s}) " "überschrieben." -#: ../src/mesh/impls/bout/boutmesh.cxx:552 +#: ../src/mesh/impls/bout/boutmesh.cxx:588 #, fuzzy msgid "Possible boundary regions are: " msgstr "Keine Randregionen auf diesem Prozessor" -#: ../src/bout++.cxx:538 +#: ../src/bout++.cxx:545 #, fuzzy, c++-format msgid "" "Processor number: {:d} of {:d}\n" @@ -744,32 +745,32 @@ msgstr "" "Prozessorennummer: {:d} von {:d}\n" "\n" -#: ../src/mesh/mesh.cxx:609 +#: ../src/mesh/mesh.cxx:642 #, fuzzy, c++-format msgid "Registered region 2D {:s}" msgstr "2D Region '{:s}' hinzugefügt" -#: ../src/mesh/mesh.cxx:599 +#: ../src/mesh/mesh.cxx:632 #, fuzzy, c++-format msgid "Registered region 3D {:s}" msgstr "3D Region '{:s}' hinzugefügt" -#: ../src/mesh/mesh.cxx:619 +#: ../src/mesh/mesh.cxx:652 #, fuzzy, c++-format msgid "Registered region Perp {:s}" msgstr "Perp Region '{:s}' hinzugefügt" -#: ../src/bout++.cxx:529 +#: ../src/bout++.cxx:536 #, fuzzy, c++-format msgid "Revision: {:s}\n" msgstr "Revision: {:s}\n" -#: ../src/solver/solver.cxx:581 +#: ../src/solver/solver.cxx:587 msgid "Run time : " msgstr "Dauer: " #. / Run the solver -#: ../src/solver/solver.cxx:525 +#: ../src/solver/solver.cxx:533 msgid "" "Running simulation\n" "\n" @@ -781,7 +782,7 @@ msgstr "" msgid "Signal" msgstr "" -#: ../src/bout++.cxx:865 +#: ../src/bout++.cxx:876 msgid "" "Sim Time | RHS evals | Wall Time | Calc Inv Comm I/O SOLVER\n" "\n" @@ -790,7 +791,7 @@ msgstr "" "Integrator\n" "\n" -#: ../src/bout++.cxx:868 +#: ../src/bout++.cxx:879 msgid "" "Sim Time | RHS_e evals | RHS_I evals | Wall Time | Calc Inv " "Comm I/O SOLVER\n" @@ -800,18 +801,18 @@ msgstr "" "Komm I/O Integrator\n" "\n" -#: ../src/solver/solver.cxx:506 +#: ../src/solver/solver.cxx:514 #, fuzzy, c++-format msgid "Solver running for {:d} outputs with monitor timestep of {:e}\n" msgstr "" "Integriere mit einem `Monitor`-Zeitschritt von {1:e} für {0:d} Aufrufe.\n" -#: ../src/solver/solver.cxx:502 +#: ../src/solver/solver.cxx:510 #, fuzzy, c++-format msgid "Solver running for {:d} outputs with output timestep of {:e}\n" msgstr "Integriere {:d} Zeitschritte von je {:e}\n" -#: ../src/solver/solver.cxx:781 +#: ../src/solver/solver.cxx:788 #, fuzzy, c++-format msgid "" "Solver::addMonitor: Cannot reduce timestep (from {:g} to {:g}) after init is " @@ -820,7 +821,7 @@ msgstr "" "Der Integrator kann den Zeitschritt nicht von {:g} auf {:g} reduzieren, " "nachdem er initialisiert wurde!" -#: ../src/solver/solver.cxx:1281 +#: ../src/solver/solver.cxx:1289 #, fuzzy, c++-format msgid "" "Time derivative at wrong location - Field is at {:s}, derivative is at {:s} " @@ -829,27 +830,27 @@ msgstr "" "Die zeitliche Ableitung ist an der falschen Stelle. Das Feld '{2:s}' ist an " "Position {0:s}, während die Ableitung an Position {1:s} ist.\n" -#: ../src/solver/solver.cxx:1480 +#: ../src/solver/solver.cxx:1494 #, fuzzy, c++-format msgid "Time derivative for variable '{:s}' not set" msgstr "Zeitliche Ableitung für Variable '{:s}' nicht gesetzt" -#: ../src/mesh/mesh.cxx:605 +#: ../src/mesh/mesh.cxx:638 #, fuzzy, c++-format msgid "Trying to add an already existing region {:s} to regionMap2D" msgstr "Die Region '{:s}' ist bereits vorhanden in der regionMap2D" -#: ../src/mesh/mesh.cxx:595 +#: ../src/mesh/mesh.cxx:614 #, fuzzy, c++-format msgid "Trying to add an already existing region {:s} to regionMap3D" msgstr "Die Region '{:s}' ist bereits vorhanden in der regionMap3D" -#: ../src/mesh/mesh.cxx:616 +#: ../src/mesh/mesh.cxx:649 #, fuzzy, c++-format msgid "Trying to add an already existing region {:s} to regionMapPerp" msgstr "Die Region '{:s}' ist bereits vorhanden in der regionMapPerp" -#: ../src/sys/options.cxx:99 ../src/sys/options.cxx:138 +#: ../src/sys/options.cxx:112 ../src/sys/options.cxx:151 #, c++-format msgid "" "Trying to index Option '{0}' with '{1}', but '{0}' is a value, not a " @@ -858,7 +859,7 @@ msgid "" "rename one of them.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:1462 +#: ../src/mesh/coordinates.cxx:1464 msgid "" "Unrecognised paralleltransform option.\n" "Valid choices are 'identity', 'shifted', 'fci'" @@ -866,31 +867,31 @@ msgstr "" "Unbekannte Paralleltransformation\n" "Gültige Optionen sind 'identity', 'shifted', 'fci'" -#: ../src/sys/options.cxx:872 +#: ../src/sys/options.cxx:899 msgid "Unused options:\n" msgstr "Ungenutzte Optionen:\n" -#: ../src/bout++.cxx:439 +#: ../src/bout++.cxx:446 #, fuzzy, c++-format msgid "Usage is {:s} -d \n" msgstr "Benutzung: {:s} -d \n" -#: ../src/bout++.cxx:448 +#: ../src/bout++.cxx:455 #, fuzzy, c++-format msgid "Usage is {:s} -f \n" msgstr "Benutzung: {:s} -f \n" -#: ../src/bout++.cxx:466 +#: ../src/bout++.cxx:473 #, fuzzy, c++-format msgid "Usage is {:s} -l \n" msgstr "Benutzung: {:s} -f \n" -#: ../src/bout++.cxx:457 +#: ../src/bout++.cxx:464 #, fuzzy, c++-format msgid "Usage is {:s} -o \n" msgstr "Benutzung: {:s} -f \n" -#: ../src/bout++.cxx:353 +#: ../src/bout++.cxx:360 #, fuzzy, c++-format msgid "Usage is {} {} \n" msgstr "Benutzung: {:s} -f \n" @@ -901,7 +902,7 @@ msgstr "" #. Print help message -- note this will be displayed once per processor as we've not #. started MPI yet. -#: ../src/bout++.cxx:367 +#: ../src/bout++.cxx:374 #, fuzzy, c++-format msgid "" "Usage: {:s} [-d ] [-f ] [restart [append]] " @@ -911,68 +912,73 @@ msgstr "" "[VAR=WERT]\n" #. restart file should be written by physics model -#: ../src/solver/solver.cxx:921 +#: ../src/solver/solver.cxx:927 #, fuzzy msgid "User signalled to quit. Returning\n" msgstr "Beendigung durch Monitor\n" -#: ../src/sys/options.cxx:373 +#: ../src/sys/options.cxx:486 +#, fuzzy, c++-format +msgid "Value for option {:s} = {:e} is not a bool" +msgstr "Wert der Option {:s} = {:e} ist keine Ganzzahl" + +#: ../src/sys/options.cxx:426 #, fuzzy, c++-format msgid "Value for option {:s} = {:e} is not an integer" msgstr "Wert der Option {:s} = {:e} ist keine Ganzzahl" -#: ../src/sys/options.cxx:408 +#: ../src/sys/options.cxx:456 #, c++-format msgid "Value for option {:s} cannot be converted to a BoutReal" msgstr "" -#: ../src/sys/options.cxx:581 +#: ../src/sys/options.cxx:623 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to a Field2D" msgstr "Wert der Option {:s} = {:e} ist keine Ganzzahl" -#: ../src/sys/options.cxx:529 +#: ../src/sys/options.cxx:571 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to a Field3D" msgstr "Wert der Option {:s} = {:e} ist keine Ganzzahl" -#: ../src/sys/options.cxx:663 +#: ../src/sys/options.cxx:705 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to a FieldPerp" msgstr "Wert der Option {:s} = {:e} ist keine Ganzzahl" -#: ../src/sys/options.cxx:451 +#: ../src/sys/options.cxx:491 #, c++-format msgid "Value for option {:s} cannot be converted to a bool" msgstr "" -#: ../src/sys/options.cxx:709 +#: ../src/sys/options.cxx:751 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to an Array" msgstr "Wert der Option {:s} = {:e} ist keine Ganzzahl" -#: ../src/sys/options.cxx:736 +#: ../src/sys/options.cxx:773 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to an Matrix" msgstr "Wert der Option {:s} = {:e} ist keine Ganzzahl" -#: ../src/sys/options.cxx:763 +#: ../src/sys/options.cxx:795 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to an Tensor" msgstr "Wert der Option {:s} = {:e} ist keine Ganzzahl" #. Another type which can't be converted -#: ../src/sys/options.cxx:365 +#: ../src/sys/options.cxx:418 #, fuzzy, c++-format msgid "Value for option {:s} is not an integer" msgstr "Wert der Option {:s} = {:e} ist keine Ganzzahl" -#: ../src/solver/solver.cxx:1232 ../src/solver/solver.cxx:1238 +#: ../src/solver/solver.cxx:1240 ../src/solver/solver.cxx:1246 #, fuzzy, c++-format msgid "Variable '{:s}' not initialised" msgstr "Variable '{:s}' ist nicht initialisiert" -#: ../src/mesh/impls/bout/boutmesh.cxx:431 +#: ../src/mesh/impls/bout/boutmesh.cxx:467 #, fuzzy, c++-format msgid "" "WARNING: Number of toroidal points should be 2^n for efficient FFT " @@ -981,27 +987,27 @@ msgstr "" "WARNUNG: Anzahl der toroidalen Punkte sollte 2^n für effiziente FFTs sein. " "Ändere MZ falls FFTs verwendet werden\n" -#: ../src/mesh/coordinates.cxx:633 +#: ../src/mesh/coordinates.cxx:635 msgid "WARNING: extrapolating input mesh quantities into x-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:410 +#: ../src/mesh/coordinates.cxx:412 msgid "" "WARNING: extrapolating input mesh quantities into x-boundary cells. Set " "option extrapolate_x=false to disable this.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:638 +#: ../src/mesh/coordinates.cxx:640 msgid "WARNING: extrapolating input mesh quantities into y-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:415 +#: ../src/mesh/coordinates.cxx:417 msgid "" "WARNING: extrapolating input mesh quantities into y-boundary cells. Set " "option extrapolate_y=false to disable this.\n" msgstr "" -#: ../src/bout++.cxx:814 +#: ../src/bout++.cxx:825 msgid "Wall time limit in hours. By default (< 0), no limit" msgstr "" @@ -1011,10 +1017,18 @@ msgid "Writing options to file {:s}\n" msgstr "Optionen werden in {:s} gespeichert\n" #. / The source label given to default values -#: ../src/sys/options.cxx:15 +#: ../src/sys/options.cxx:34 msgid "default" msgstr "Vorgabe" +#, fuzzy, c++-format +#~ msgid "\tOpenMP parallelisation {}" +#~ msgstr "\tOpenMP Parallelisierung ist deaktiviert\n" + +#, fuzzy, c++-format +#~ msgid "\tOption '{:s}': Boolean expected. Got '{:s}'\n" +#~ msgstr "\tOption '{:s}': Boolscherwert erwartet, '{:s}' gefunden\n" + #~ msgid "\tChecking disabled\n" #~ msgstr "\tChecks sind deaktiviert\n" @@ -1022,10 +1036,6 @@ msgstr "Vorgabe" #~ msgid "\tChecking enabled, level {:d}\n" #~ msgstr "\tChecks der Stufe {:d} sind aktiviert\n" -#, fuzzy -#~ msgid "\tOpenMP parallelisation enabled, using {:d} threads\n" -#~ msgstr "\tOpenMP Parallelisierung mit {:d} Threads ist aktiviert\n" - #~ msgid "\tSignal handling enabled\n" #~ msgstr "\tSignalverarbeitung ist aktiviert\n" @@ -1051,8 +1061,8 @@ msgstr "Vorgabe" #~ "überschrieben. Benötigt `restart`\n" #~ " VAR=WERT \t\tSetzt den Wert WERT für die Variable VAR\n" #~ "\n" -#~ "Weitere Eingabeparameter sind in dem Manual und dem Quellcode (z.B. {:s}." -#~ "cxx) des Physikmoduls definiert.\n" +#~ "Weitere Eingabeparameter sind in dem Manual und dem Quellcode (z.B. " +#~ "{:s}.cxx) des Physikmoduls definiert.\n" #, fuzzy #~ msgid "Couldn't get BoutReal from option {:s} = '{:s}'" diff --git a/locale/es/libbout.po b/locale/es/libbout.po index 8a3b22be61..68db78ada9 100644 --- a/locale/es/libbout.po +++ b/locale/es/libbout.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: BOUT++ 4.2.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-09-12 09:17+0100\n" +"POT-Creation-Date: 2025-08-13 23:37+0100\n" "PO-Revision-Date: 2019-02-11 12:46+0900\n" "Last-Translator: Marta \n" "Language-Team: Spanish\n" @@ -16,7 +16,7 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:191 +#: ../src/mesh/impls/bout/boutmesh.cxx:182 #, fuzzy, c++-format msgid "" "\t -> Core region jyseps2_1-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " @@ -25,7 +25,7 @@ msgstr "" "\t -> La región `Core` jyseps2_1-jyseps1_1 ({:d}-{:d} = {:d}) debe ser un " "múltiplo de MYSUB ({:d})\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:224 +#: ../src/mesh/impls/bout/boutmesh.cxx:215 #, fuzzy, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " @@ -34,7 +34,7 @@ msgstr "" "\t -> La región `Core` jyseps2_2-jyseps1_1 ({:d}-{:d} = {:d}) debe ser un " "múltiplo de MYSUB ({:d})\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:199 +#: ../src/mesh/impls/bout/boutmesh.cxx:190 #, fuzzy, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_2 ({:d}-{:d} = {:d}) must be a multiple " @@ -43,11 +43,11 @@ msgstr "" "\t -> La región `Core` jyseps2_2-jyseps1_2 ({:d}-{:d} = {:d}) debe ser un " "múltiplo de MYSUB ({:d})\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:309 +#: ../src/mesh/impls/bout/boutmesh.cxx:300 msgid "\t -> Good value\n" msgstr "\t -> El valor es bueno\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:180 +#: ../src/mesh/impls/bout/boutmesh.cxx:171 #, fuzzy, c++-format msgid "" "\t -> Leg region jyseps1_1+1 ({:d}) must be a multiple of MYSUB ({:d})\n" @@ -55,7 +55,7 @@ msgstr "" "\t -> La región `Leg` jyseps1_1+1 ({:d}) debe ser un múltiplo de MYSUB " "({:d})\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:215 +#: ../src/mesh/impls/bout/boutmesh.cxx:206 #, fuzzy, c++-format msgid "" "\t -> leg region jyseps1_2-ny_inner+1 ({:d}-{:d}+1 = {:d}) must be a " @@ -64,7 +64,7 @@ msgstr "" "\t -> La región `Leg` jyseps1_2-ny_inner+1 ({:d}-{:d}+1 = {:d}) debe ser un " "múltiplo de MYSUB ({:d})\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:232 +#: ../src/mesh/impls/bout/boutmesh.cxx:223 #, fuzzy, c++-format msgid "" "\t -> leg region ny-jyseps2_2-1 ({:d}-{:d}-1 = {:d}) must be a multiple of " @@ -73,7 +73,7 @@ msgstr "" "\t -> La región `Leg` ny-jyseps2_2-1 ({:d}-{:d}-1 = {:d}) debe ser un " "múltiplo de MYSUB ({:d})\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:208 +#: ../src/mesh/impls/bout/boutmesh.cxx:199 #, fuzzy, c++-format msgid "" "\t -> leg region ny_inner-jyseps2_1-1 ({:d}-{:d}-1 = {:d}) must be a " @@ -82,12 +82,17 @@ msgstr "" "\t -> La región `Leg` ny_inner-jyseps2_1-1 ({:d}-{:d}-1 = {:d}) debe ser un " "múltiplo de MYSUB ({:d})\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:175 +#: ../src/mesh/impls/bout/boutmesh.cxx:166 #, fuzzy, c++-format msgid "\t -> ny/NYPE ({:d}/{:d} = {:d}) must be >= MYG ({:d})\n" msgstr "\t -> ny/NYPE ({:d}/{:d} = {:d}) debe ser >= MYG ({:d})\n" #: ../src/bout++.cxx:575 +#, fuzzy, c++-format +msgid "\tADIOS2 support {}\n" +msgstr "\tSoporte netCDF activado\n" + +#: ../src/bout++.cxx:583 #, c++-format msgid "\tBacktrace in exceptions {}\n" msgstr "" @@ -96,28 +101,28 @@ msgstr "" #. Processors divide equally #. Mesh in X divides equally #. Mesh in Y divides equally -#: ../src/mesh/impls/bout/boutmesh.cxx:297 +#: ../src/mesh/impls/bout/boutmesh.cxx:288 #, fuzzy, c++-format msgid "\tCandidate value: {:d}\n" msgstr "\tValor candidato: {:d}\n" -#: ../src/bout++.cxx:576 +#: ../src/bout++.cxx:584 #, c++-format msgid "\tColour in logs {}\n" msgstr "" -#: ../src/bout++.cxx:594 +#: ../src/bout++.cxx:599 msgid "\tCommand line options for this run : " msgstr "\tParámetros de línea de comandos para esta ejecución :" #. The stringify is needed here as BOUT_FLAGS_STRING may already contain quoted strings #. which could cause problems (e.g. terminate strings). -#: ../src/bout++.cxx:590 +#: ../src/bout++.cxx:595 #, fuzzy, c++-format msgid "\tCompiled with flags : {:s}\n" msgstr "\tCompilado con las opciones `flags` : {:s}\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:324 +#: ../src/mesh/impls/bout/boutmesh.cxx:315 #, fuzzy, c++-format msgid "" "\tDomain split (NXPE={:d}, NYPE={:d}) into domains (localNx={:d}, " @@ -126,14 +131,14 @@ msgstr "" "\tDominio separado (NXPE={:d}, NYPE={:d}) en los dominios (localNx={:d}, " "localNy={:d})\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:364 +#: ../src/mesh/impls/bout/boutmesh.cxx:357 #, fuzzy, c++-format msgid "\tERROR: Cannot split {:d} Y points equally between {:d} processors\n" msgstr "" "\tERROR: No se pueden separar {:d} Y puntos entre {:d} procesadores por " "igual\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:372 +#: ../src/mesh/impls/bout/boutmesh.cxx:365 #, fuzzy, c++-format msgid "\tERROR: Cannot split {:d} Z points equally between {:d} processors\n" msgstr "" @@ -154,31 +159,31 @@ msgstr "" msgid "\tEmpty key or value in command line '{:s}'\n" msgstr "\tEntrada o valor vacío en la línea de comandos '{:s}'\n" -#: ../src/bout++.cxx:582 +#: ../src/bout++.cxx:587 #, c++-format msgid "\tExtra debug output {}\n" msgstr "" -#: ../src/bout++.cxx:561 +#: ../src/bout++.cxx:568 #, fuzzy, c++-format msgid "\tFFT support {}\n" msgstr "\tSoporte netCDF activado\n" -#: ../src/bout++.cxx:585 +#: ../src/bout++.cxx:590 #, c++-format msgid "\tField name tracking {}\n" msgstr "" -#: ../src/bout++.cxx:583 +#: ../src/bout++.cxx:588 #, c++-format msgid "\tFloating-point exceptions {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:440 +#: ../src/mesh/impls/bout/boutmesh.cxx:476 msgid "\tGrid size: " msgstr "\tTamaño de la malla (`grid`): " -#: ../src/mesh/impls/bout/boutmesh.cxx:463 +#: ../src/mesh/impls/bout/boutmesh.cxx:499 #, fuzzy msgid "\tGuard cells (x,y,z): " msgstr "\tProteger celdas (x,y): " @@ -192,17 +197,17 @@ msgstr "" "\tLa entrada no debe contener el carácter ':'\n" "\tLínea: {:s}" -#: ../src/bout++.cxx:563 +#: ../src/bout++.cxx:570 #, c++-format msgid "\tLAPACK support {}\n" msgstr "" -#: ../src/bout++.cxx:586 +#: ../src/bout++.cxx:591 #, c++-format msgid "\tMessage stack {}\n" msgstr "" -#: ../src/bout++.cxx:560 +#: ../src/bout++.cxx:567 #, c++-format msgid "\tMetrics mode is {}\n" msgstr "" @@ -212,98 +217,95 @@ msgstr "" msgid "\tMultiple '=' in command-line argument '{:s}'\n" msgstr "\tMutilples '=' en el argumento de la línea de comandos '{:s}'\n" -#: ../src/bout++.cxx:562 +#: ../src/bout++.cxx:569 #, c++-format msgid "\tNatural language support {}\n" msgstr "" -#: ../src/bout++.cxx:567 +#: ../src/bout++.cxx:574 #, fuzzy, c++-format msgid "\tNetCDF support {}{}\n" msgstr "\tSoporte netCDF activado\n" -#: ../src/bout++.cxx:577 +#: ../src/bout++.cxx:585 #, fuzzy, c++-format -msgid "\tOpenMP parallelisation {}" -msgstr "\tParalelización en OpenMP desactivada\n" +msgid "\tOpenMP parallelisation {}, using {} threads\n" +msgstr "" +"\tParalelización en OpenMP activada, usando {:d} procesos (`threads`)\n" #. Mark the option as used #. Option not found -#: ../src/sys/options.cxx:311 ../src/sys/options.cxx:380 -#: ../src/sys/options.cxx:415 ../src/sys/options.cxx:457 -#: ../src/sys/options.cxx:717 ../src/sys/options.cxx:744 -#: ../src/sys/options.cxx:771 ../include/bout/options.hxx:516 -#: ../include/bout/options.hxx:549 ../include/bout/options.hxx:573 -#: ../include/bout/options.hxx:820 +#: ../include/bout/options.hxx:586 ../include/bout/options.hxx:619 +#: ../include/bout/options.hxx:643 ../include/bout/options.hxx:896 msgid "\tOption " msgstr "\tOpción " -#: ../src/sys/options.cxx:447 +#: ../src/sys/options.cxx:369 #, fuzzy, c++-format -msgid "\tOption '{:s}': Boolean expected. Got '{:s}'\n" -msgstr "\tOpción '{:s}': valor Booleano esperado. Se obtuvo '{:s}'\n" +msgid "\tOption {} = {}" +msgstr "\tOpción " #: ../src/sys/options/options_ini.cxx:70 #, fuzzy, c++-format msgid "\tOptions file '{:s}' not found\n" msgstr "\tOpciones de archivo '{:s}' no encontrados\n" -#: ../src/bout++.cxx:568 +#: ../src/bout++.cxx:576 #, c++-format msgid "\tPETSc support {}\n" msgstr "" -#: ../src/bout++.cxx:571 +#: ../src/bout++.cxx:579 #, c++-format msgid "\tPVODE support {}\n" msgstr "" -#: ../src/bout++.cxx:557 +#: ../src/bout++.cxx:564 msgid "\tParallel NetCDF support disabled\n" msgstr "\tSoporte para NetCDF paralelo desactivado\n" -#: ../src/bout++.cxx:555 +#: ../src/bout++.cxx:562 msgid "\tParallel NetCDF support enabled\n" msgstr "\tSoporte para NetCDF paralelo activado\n" -#: ../src/bout++.cxx:569 +#: ../src/bout++.cxx:577 #, c++-format msgid "\tPretty function name support {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:437 +#: ../src/mesh/impls/bout/boutmesh.cxx:473 msgid "\tRead nz from input grid file\n" msgstr "\tLeer nz del archivo input de la malla `grid`\n" -#: ../src/mesh/mesh.cxx:238 +#: ../src/mesh/mesh.cxx:249 msgid "\tReading contravariant vector " msgstr "\tLeyendo vector contravariante " -#: ../src/mesh/mesh.cxx:231 ../src/mesh/mesh.cxx:252 +#: ../src/mesh/mesh.cxx:242 ../src/mesh/mesh.cxx:263 msgid "\tReading covariant vector " msgstr "\tLeyendo vector covariante " -#: ../src/bout++.cxx:548 +#: ../src/bout++.cxx:555 #, c++-format msgid "\tRuntime error checking {}" msgstr "" -#: ../src/bout++.cxx:573 +#: ../src/bout++.cxx:581 #, c++-format msgid "\tSLEPc support {}\n" msgstr "" -#: ../src/bout++.cxx:574 +#: ../src/bout++.cxx:582 #, c++-format msgid "\tSUNDIALS support {}\n" msgstr "" -#: ../src/bout++.cxx:572 +#: ../src/bout++.cxx:580 #, c++-format msgid "\tScore-P support {}\n" msgstr "" -#: ../src/bout++.cxx:584 +#: ../src/bout++.cxx:589 #, fuzzy, c++-format msgid "\tSignal handling support {}\n" msgstr "\tGestión de señal desactivada\n" @@ -313,7 +315,7 @@ msgstr "\tGestión de señal desactivada\n" msgid "\tUsing a timestep {:e}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:577 +#: ../src/mesh/impls/bout/boutmesh.cxx:613 msgid "\tdone\n" msgstr "\tlisto\n" @@ -323,7 +325,7 @@ msgid "" "\tSplit Runge-Kutta-Legendre and SSP-RK3 solver\n" msgstr "" -#: ../src/bout++.cxx:371 +#: ../src/bout++.cxx:378 #, fuzzy msgid "" "\n" @@ -343,7 +345,7 @@ msgstr "" " -v, --verbose\t\tAumentar verbosidad\n" " -q, --quiet\t\tDisminuir verbosidad\n" -#: ../src/sys/expressionparser.cxx:302 +#: ../src/sys/expressionparser.cxx:341 #, c++-format msgid "" "\n" @@ -351,7 +353,7 @@ msgid "" " Did you mean '{0}'?" msgstr "" -#: ../src/solver/solver.cxx:580 +#: ../src/solver/solver.cxx:586 #, fuzzy, c++-format msgid "" "\n" @@ -360,7 +362,7 @@ msgstr "" "\n" "Ejecución finalizada en : {:s}\n" -#: ../src/solver/solver.cxx:532 +#: ../src/solver/solver.cxx:540 #, fuzzy, c++-format msgid "" "\n" @@ -372,7 +374,7 @@ msgstr "" #. Raw string to help with the formatting of the message, and a #. separate variable so clang-format doesn't barf on the #. exception -#: ../src/sys/options.cxx:1102 +#: ../src/sys/options.cxx:1158 msgid "" "\n" "There were unused input options:\n" @@ -400,7 +402,7 @@ msgid "" "{}" msgstr "" -#: ../src/bout++.cxx:382 +#: ../src/bout++.cxx:389 #, c++-format msgid "" " --print-config\t\tPrint the compile-time configuration\n" @@ -433,57 +435,57 @@ msgid "" "model source (e.g. {:s}.cxx)\n" msgstr "" -#: ../src/bout++.cxx:379 +#: ../src/bout++.cxx:386 #, fuzzy msgid " -c, --color\t\t\tColor output using bout-log-color\n" msgstr " -c, --color\t\tSalida de color usando bout-log-color\n" -#: ../include/bout/options.hxx:823 +#: ../include/bout/options.hxx:899 msgid ") overwritten with:" msgstr "" -#: ../src/bout++.cxx:550 +#: ../src/bout++.cxx:557 #, c++-format msgid ", level {}" msgstr "" -#: ../src/bout++.cxx:579 -#, c++-format -msgid ", using {} threads" -msgstr "" - #: ../tests/unit/src/test_bout++.cxx:352 msgid "4 of 8" msgstr "" -#: ../src/sys/options.cxx:868 +#: ../src/sys/options.cxx:895 msgid "All options used\n" msgstr "Usando todas las opciones\n" -#: ../src/bout++.cxx:528 +#: ../src/bout++.cxx:535 #, fuzzy, c++-format msgid "BOUT++ version {:s}\n" msgstr "Versión de BOUT++ {:s}\n" -#: ../src/bout++.cxx:143 +#: ../src/bout++.cxx:147 #, fuzzy msgid "Bad command line arguments:\n" msgstr "\tMutilples '=' en el argumento de la línea de comandos '{:s}'\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:559 +#: ../src/sys/expressionparser.cxx:192 +#, c++-format +msgid "Boolean operator argument {:e} is not a bool" +msgstr "" + +#: ../src/mesh/impls/bout/boutmesh.cxx:595 msgid "Boundary regions in this processor: " msgstr "Regiones frontera en este procesador: " -#: ../src/mesh/impls/bout/boutmesh.cxx:355 +#: ../src/mesh/impls/bout/boutmesh.cxx:348 #, fuzzy, c++-format msgid "Cannot split {:d} X points equally between {:d} processors\n" msgstr "No se pueden dividir {:d} X points entre {:d} procesadores por igual\n" -#: ../src/bout++.cxx:818 +#: ../src/bout++.cxx:829 msgid "Check if a file exists, and exit if it does." msgstr "" -#: ../src/bout++.cxx:533 +#: ../src/bout++.cxx:540 #, fuzzy, c++-format msgid "" "Code compiled on {:s} at {:s}\n" @@ -496,7 +498,7 @@ msgstr "" msgid "Command line" msgstr "Línea de comandos" -#: ../src/bout++.cxx:544 ../tests/unit/src/test_bout++.cxx:358 +#: ../src/bout++.cxx:551 ../tests/unit/src/test_bout++.cxx:358 msgid "Compile-time options:\n" msgstr "Opciones de tiempo de compilación:\n" @@ -505,16 +507,16 @@ msgstr "Opciones de tiempo de compilación:\n" msgid "Compiled with flags" msgstr "\tCompilado con las opciones `flags` : {:s}\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:568 +#: ../src/mesh/impls/bout/boutmesh.cxx:604 msgid "Constructing default regions" msgstr "Construyendo regiones por defecto" -#: ../src/bout++.cxx:520 +#: ../src/bout++.cxx:527 #, fuzzy, c++-format msgid "Could not create PID file {:s}" msgstr "No se pudo abrir el archivo de salida `output` '{:s}'\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:318 +#: ../src/mesh/impls/bout/boutmesh.cxx:309 msgid "" "Could not find a valid value for NXPE. Try a different number of processors." msgstr "" @@ -526,30 +528,30 @@ msgstr "" msgid "Could not open output file '{:s}'\n" msgstr "No se pudo abrir el archivo de salida `output` '{:s}'\n" -#: ../src/bout++.cxx:652 +#: ../src/bout++.cxx:657 #, c++-format msgid "Could not open {:s}/{:s}.{:d} for writing" msgstr "" #. Error reading -#: ../src/mesh/mesh.cxx:532 +#: ../src/mesh/mesh.cxx:543 #, fuzzy, c++-format msgid "Could not read integer array '{:s}'\n" msgstr "No se pudo leer la matriz de enteros '{:s}'\n" #. Failed . Probably not important enough to stop the simulation -#: ../src/bout++.cxx:632 +#: ../src/bout++.cxx:637 msgid "Could not run bout-log-color. Make sure it is in your PATH\n" msgstr "" "No se pudo ejecutar bout-log-color. Asegúrese de que se encuentre en su " "PATH\n" -#: ../src/solver/solver.cxx:765 +#: ../src/solver/solver.cxx:772 #, fuzzy, c++-format msgid "Couldn't add Monitor: {:g} is not a multiple of {:g}!" msgstr "No se pudo añadir el Monitor: {:g} no és multiplo de {:g}!" -#: ../src/sys/expressionparser.cxx:273 +#: ../src/sys/expressionparser.cxx:312 #, c++-format msgid "" "Couldn't find generator '{}'. BOUT++ expressions are now case-sensitive, so " @@ -558,69 +560,69 @@ msgid "" "{}" msgstr "" -#: ../src/mesh/mesh.cxx:568 +#: ../src/mesh/mesh.cxx:587 #, fuzzy, c++-format msgid "Couldn't find region {:s} in regionMap2D" msgstr "No se pudo encontrar la región {:s} en regionMap2D" -#: ../src/mesh/mesh.cxx:560 +#: ../src/mesh/mesh.cxx:571 ../src/mesh/mesh.cxx:579 #, fuzzy, c++-format msgid "Couldn't find region {:s} in regionMap3D" msgstr "No se pudo encontrar la región {:s} en regionMap2D" -#: ../src/mesh/mesh.cxx:576 +#: ../src/mesh/mesh.cxx:595 #, fuzzy, c++-format msgid "Couldn't find region {:s} in regionMapPerp" msgstr "No se pudo encontrar la región {:s} en regionMapPerp" #. Convert any exceptions to something a bit more useful -#: ../src/sys/options.cxx:336 +#: ../src/sys/options.cxx:361 #, fuzzy, c++-format msgid "Couldn't get {} from option {:s} = '{:s}': {}" msgstr "No se pudo recuperar el entero de la opción {:s} = '{:s}'" -#: ../src/bout++.cxx:508 +#: ../src/bout++.cxx:515 #, fuzzy, c++-format msgid "DataDir \"{:s}\" does not exist or is not accessible\n" msgstr "DataDir \"{:s}\" no existe o no es accessible\n" -#: ../src/bout++.cxx:505 +#: ../src/bout++.cxx:512 #, fuzzy, c++-format msgid "DataDir \"{:s}\" is not a directory\n" msgstr "DataDir \"{:s}\" no es un directorio\n" -#: ../src/solver/solver.cxx:665 +#: ../src/solver/solver.cxx:671 msgid "ERROR: Solver is already initialised\n" msgstr "ERROR: el Solver ya se encuentra inicializado\n" -#: ../src/bout++.cxx:209 +#: ../src/bout++.cxx:216 #, fuzzy, c++-format msgid "Error encountered during initialisation: {:s}\n" msgstr "Error encontrado durante la inicialización:{:s}\n" -#: ../src/bout++.cxx:744 +#: ../src/bout++.cxx:751 msgid "Error whilst writing settings" msgstr "Error durante el paso de opciones" -#: ../src/mesh/impls/bout/boutmesh.cxx:332 +#: ../src/mesh/impls/bout/boutmesh.cxx:323 #, fuzzy, c++-format msgid "Error: nx must be greater than 2 times MXG (2 * {:d})" msgstr "Error: nx debe ser mayor que 2 veces MXG (2 * {:d})" -#: ../src/solver/solver.cxx:512 +#: ../src/solver/solver.cxx:520 msgid "Failed to initialise solver-> Aborting\n" msgstr "Fallo en inicializar el solver-> Abortando\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:290 +#: ../src/mesh/impls/bout/boutmesh.cxx:281 #, fuzzy, c++-format msgid "Finding value for NXPE (ideal = {:f})\n" msgstr "Encontrando valor para NXPE (ideal = {:f})\n" -#: ../src/solver/solver.cxx:668 +#: ../src/solver/solver.cxx:674 msgid "Initialising solver\n" msgstr "Initializando el solver\n" -#: ../src/bout++.cxx:494 +#: ../src/bout++.cxx:501 msgid "" "Input and output file for settings must be different.\n" "Provide -o to avoid this issue.\n" @@ -633,48 +635,48 @@ msgstr "" msgid "Invalid command line option '-' found - maybe check whitespace?" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:400 +#: ../src/mesh/impls/bout/boutmesh.cxx:436 msgid "Loading mesh" msgstr "Cargando malla `mesh`" -#: ../src/mesh/impls/bout/boutmesh.cxx:415 +#: ../src/mesh/impls/bout/boutmesh.cxx:451 msgid "Mesh must contain nx" msgstr "La malla `mesh` debe contener nx" -#: ../src/mesh/impls/bout/boutmesh.cxx:419 +#: ../src/mesh/impls/bout/boutmesh.cxx:455 msgid "Mesh must contain ny" msgstr "La malla `mesh` debe contener ny" #. Not found -#: ../src/mesh/mesh.cxx:536 +#: ../src/mesh/mesh.cxx:547 #, fuzzy, c++-format msgid "Missing integer array {:s}\n" msgstr "Fala la matriz entera {:s}\n" -#: ../src/solver/solver.cxx:905 +#: ../src/solver/solver.cxx:911 #, fuzzy, c++-format msgid "Monitor signalled to quit (exception {})\n" msgstr "Monitor indicó salir\n" -#: ../src/solver/solver.cxx:883 +#: ../src/solver/solver.cxx:889 #, fuzzy, c++-format msgid "Monitor signalled to quit (return code {})" msgstr "Monitor indicó salir" -#: ../src/bout++.cxx:823 +#: ../src/bout++.cxx:834 msgid "Name of file whose existence triggers a stop" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:565 +#: ../src/mesh/impls/bout/boutmesh.cxx:601 msgid "No boundary regions in this processor" msgstr "Sin regiones de frontera en este procesador" -#: ../src/mesh/impls/bout/boutmesh.cxx:550 +#: ../src/mesh/impls/bout/boutmesh.cxx:586 #, fuzzy msgid "No boundary regions; domain is periodic\n" msgstr "Sin regiones de frontera en este procesador" -#: ../src/mesh/impls/bout/boutmesh.cxx:254 +#: ../src/mesh/impls/bout/boutmesh.cxx:245 #, fuzzy, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in x direction ({:d})\n" @@ -682,7 +684,7 @@ msgstr "" "Número de procesadores ({:d}) no divisible para NPs en la dirección x " "({:d})\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:267 +#: ../src/mesh/impls/bout/boutmesh.cxx:258 #, fuzzy, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in y direction ({:d})\n" @@ -691,26 +693,26 @@ msgstr "" "({:d})\n" #. Less than 2 time-steps left -#: ../src/bout++.cxx:896 +#: ../src/bout++.cxx:908 #, fuzzy, c++-format msgid "Only {:e} seconds ({:.2f} steps) left. Quitting\n" msgstr "Solo faltan {:e} segundos. Saliendo\n" -#: ../src/sys/options.cxx:303 ../src/sys/options.cxx:345 -#: ../src/sys/options.cxx:393 ../src/sys/options.cxx:428 -#: ../src/sys/options.cxx:703 ../src/sys/options.cxx:730 -#: ../src/sys/options.cxx:757 +#: ../src/sys/options.cxx:382 ../src/sys/options.cxx:398 +#: ../src/sys/options.cxx:441 ../src/sys/options.cxx:471 +#: ../src/sys/options.cxx:745 ../src/sys/options.cxx:767 +#: ../src/sys/options.cxx:789 #, fuzzy, c++-format msgid "Option {:s} has no value" msgstr "Opción {:s} sin valor" #. Doesn't exist -#: ../src/sys/options.cxx:159 +#: ../src/sys/options.cxx:172 #, fuzzy, c++-format msgid "Option {:s}:{:s} does not exist" msgstr "Opción {:s}:{:s} no existe" -#: ../include/bout/options.hxx:828 +#: ../include/bout/options.hxx:904 #, fuzzy, c++-format msgid "" "Options: Setting a value from same source ({:s}) to new value '{:s}' - old " @@ -719,12 +721,12 @@ msgstr "" "Opciones: Cambiando valor de la misma fuente ({:s}) al valor nuevo '{:s}' - " "valor anterior era '{:s}'." -#: ../src/mesh/impls/bout/boutmesh.cxx:552 +#: ../src/mesh/impls/bout/boutmesh.cxx:588 #, fuzzy msgid "Possible boundary regions are: " msgstr "Sin regiones de frontera en este procesador" -#: ../src/bout++.cxx:538 +#: ../src/bout++.cxx:545 #, fuzzy, c++-format msgid "" "Processor number: {:d} of {:d}\n" @@ -733,32 +735,32 @@ msgstr "" "Procesador número: {:d} de {:d}\n" "\n" -#: ../src/mesh/mesh.cxx:609 +#: ../src/mesh/mesh.cxx:642 #, fuzzy, c++-format msgid "Registered region 2D {:s}" msgstr "Región 2D registrada {:s}" -#: ../src/mesh/mesh.cxx:599 +#: ../src/mesh/mesh.cxx:632 #, fuzzy, c++-format msgid "Registered region 3D {:s}" msgstr "Región 3D registrada {:s}" -#: ../src/mesh/mesh.cxx:619 +#: ../src/mesh/mesh.cxx:652 #, fuzzy, c++-format msgid "Registered region Perp {:s}" msgstr "Región Perp registrada {:s}" -#: ../src/bout++.cxx:529 +#: ../src/bout++.cxx:536 #, fuzzy, c++-format msgid "Revision: {:s}\n" msgstr "Revisión: {:s}\n" -#: ../src/solver/solver.cxx:581 +#: ../src/solver/solver.cxx:587 msgid "Run time : " msgstr "Tiempo de ejecución : " #. / Run the solver -#: ../src/solver/solver.cxx:525 +#: ../src/solver/solver.cxx:533 msgid "" "Running simulation\n" "\n" @@ -770,7 +772,7 @@ msgstr "" msgid "Signal" msgstr "" -#: ../src/bout++.cxx:865 +#: ../src/bout++.cxx:876 msgid "" "Sim Time | RHS evals | Wall Time | Calc Inv Comm I/O SOLVER\n" "\n" @@ -779,7 +781,7 @@ msgstr "" "SOLVER\n" "\n" -#: ../src/bout++.cxx:868 +#: ../src/bout++.cxx:879 msgid "" "Sim Time | RHS_e evals | RHS_I evals | Wall Time | Calc Inv " "Comm I/O SOLVER\n" @@ -789,21 +791,21 @@ msgstr "" "Com I/O SOLVER\n" "\n" -#: ../src/solver/solver.cxx:506 +#: ../src/solver/solver.cxx:514 #, fuzzy, c++-format msgid "Solver running for {:d} outputs with monitor timestep of {:e}\n" msgstr "" "Solver corriendo para {:d} outputs con intervalos de tiempo de monitor de " "{:e}\n" -#: ../src/solver/solver.cxx:502 +#: ../src/solver/solver.cxx:510 #, fuzzy, c++-format msgid "Solver running for {:d} outputs with output timestep of {:e}\n" msgstr "" "Solver corriendo para {:d} outputs con intervalos de tiempo de output de " "{:e}\n" -#: ../src/solver/solver.cxx:781 +#: ../src/solver/solver.cxx:788 #, fuzzy, c++-format msgid "" "Solver::addMonitor: Cannot reduce timestep (from {:g} to {:g}) after init is " @@ -812,7 +814,7 @@ msgstr "" "Solver::addMonitor: No se puedo reducir el intervalo de tiempo (de {:g} a " "{:g}) después de que init fuera llamado!" -#: ../src/solver/solver.cxx:1281 +#: ../src/solver/solver.cxx:1289 #, fuzzy, c++-format msgid "" "Time derivative at wrong location - Field is at {:s}, derivative is at {:s} " @@ -821,27 +823,27 @@ msgstr "" "Derivada del tiempo en lugar erróneo - El field se encuentra en {:s}, la " "derivada se encuentra en {:s} para el field '{:s}'\n" -#: ../src/solver/solver.cxx:1480 +#: ../src/solver/solver.cxx:1494 #, fuzzy, c++-format msgid "Time derivative for variable '{:s}' not set" msgstr "Derivada del tiempo para la variable '{:s}' no fijada" -#: ../src/mesh/mesh.cxx:605 +#: ../src/mesh/mesh.cxx:638 #, fuzzy, c++-format msgid "Trying to add an already existing region {:s} to regionMap2D" msgstr "Intentando añadir una región ya existente {:s} a regionMap2D" -#: ../src/mesh/mesh.cxx:595 +#: ../src/mesh/mesh.cxx:614 #, fuzzy, c++-format msgid "Trying to add an already existing region {:s} to regionMap3D" msgstr "Intentando añadir una región ya existente {:s} a regionMap3D" -#: ../src/mesh/mesh.cxx:616 +#: ../src/mesh/mesh.cxx:649 #, fuzzy, c++-format msgid "Trying to add an already existing region {:s} to regionMapPerp" msgstr "Intentando añadir una región ya existente {:s} a regionMapPerp" -#: ../src/sys/options.cxx:99 ../src/sys/options.cxx:138 +#: ../src/sys/options.cxx:112 ../src/sys/options.cxx:151 #, c++-format msgid "" "Trying to index Option '{0}' with '{1}', but '{0}' is a value, not a " @@ -850,7 +852,7 @@ msgid "" "rename one of them.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:1462 +#: ../src/mesh/coordinates.cxx:1464 msgid "" "Unrecognised paralleltransform option.\n" "Valid choices are 'identity', 'shifted', 'fci'" @@ -858,31 +860,31 @@ msgstr "" "Opción paralleltransform desconocida.\n" "Opciones válidas son 'identity', 'shifted', 'fci'" -#: ../src/sys/options.cxx:872 +#: ../src/sys/options.cxx:899 msgid "Unused options:\n" msgstr "Opciones sin usar:\n" -#: ../src/bout++.cxx:439 +#: ../src/bout++.cxx:446 #, fuzzy, c++-format msgid "Usage is {:s} -d \n" msgstr "Correcto uso es {:s} -d \n" -#: ../src/bout++.cxx:448 +#: ../src/bout++.cxx:455 #, fuzzy, c++-format msgid "Usage is {:s} -f \n" msgstr "Correcto uso es {:s} -f \n" -#: ../src/bout++.cxx:466 +#: ../src/bout++.cxx:473 #, fuzzy, c++-format msgid "Usage is {:s} -l \n" msgstr "Correcto uso es {:s} -l \n" -#: ../src/bout++.cxx:457 +#: ../src/bout++.cxx:464 #, fuzzy, c++-format msgid "Usage is {:s} -o \n" msgstr "Correcto uso es {:s} -o \n" -#: ../src/bout++.cxx:353 +#: ../src/bout++.cxx:360 #, fuzzy, c++-format msgid "Usage is {} {} \n" msgstr "Correcto uso es {:s} -l \n" @@ -893,7 +895,7 @@ msgstr "" #. Print help message -- note this will be displayed once per processor as we've not #. started MPI yet. -#: ../src/bout++.cxx:367 +#: ../src/bout++.cxx:374 #, fuzzy, c++-format msgid "" "Usage: {:s} [-d ] [-f ] [restart [append]] " @@ -903,68 +905,73 @@ msgstr "" "[VAR=VALUE]\n" #. restart file should be written by physics model -#: ../src/solver/solver.cxx:921 +#: ../src/solver/solver.cxx:927 #, fuzzy msgid "User signalled to quit. Returning\n" msgstr "Monitor indicó salir\n" -#: ../src/sys/options.cxx:373 +#: ../src/sys/options.cxx:486 +#, fuzzy, c++-format +msgid "Value for option {:s} = {:e} is not a bool" +msgstr "Valor para la opción {:s} = {:e} no es un entero" + +#: ../src/sys/options.cxx:426 #, fuzzy, c++-format msgid "Value for option {:s} = {:e} is not an integer" msgstr "Valor para la opción {:s} = {:e} no es un entero" -#: ../src/sys/options.cxx:408 +#: ../src/sys/options.cxx:456 #, c++-format msgid "Value for option {:s} cannot be converted to a BoutReal" msgstr "" -#: ../src/sys/options.cxx:581 +#: ../src/sys/options.cxx:623 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to a Field2D" msgstr "Valor para la opción {:s} = {:e} no es un entero" -#: ../src/sys/options.cxx:529 +#: ../src/sys/options.cxx:571 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to a Field3D" msgstr "Valor para la opción {:s} = {:e} no es un entero" -#: ../src/sys/options.cxx:663 +#: ../src/sys/options.cxx:705 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to a FieldPerp" msgstr "Valor para la opción {:s} = {:e} no es un entero" -#: ../src/sys/options.cxx:451 +#: ../src/sys/options.cxx:491 #, c++-format msgid "Value for option {:s} cannot be converted to a bool" msgstr "" -#: ../src/sys/options.cxx:709 +#: ../src/sys/options.cxx:751 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to an Array" msgstr "Valor para la opción {:s} = {:e} no es un entero" -#: ../src/sys/options.cxx:736 +#: ../src/sys/options.cxx:773 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to an Matrix" msgstr "Valor para la opción {:s} = {:e} no es un entero" -#: ../src/sys/options.cxx:763 +#: ../src/sys/options.cxx:795 #, fuzzy, c++-format msgid "Value for option {:s} cannot be converted to an Tensor" msgstr "Valor para la opción {:s} = {:e} no es un entero" #. Another type which can't be converted -#: ../src/sys/options.cxx:365 +#: ../src/sys/options.cxx:418 #, fuzzy, c++-format msgid "Value for option {:s} is not an integer" msgstr "Valor para la opción {:s} = {:e} no es un entero" -#: ../src/solver/solver.cxx:1232 ../src/solver/solver.cxx:1238 +#: ../src/solver/solver.cxx:1240 ../src/solver/solver.cxx:1246 #, fuzzy, c++-format msgid "Variable '{:s}' not initialised" msgstr "Variable '{:s}' sin inicializar" -#: ../src/mesh/impls/bout/boutmesh.cxx:431 +#: ../src/mesh/impls/bout/boutmesh.cxx:467 #, fuzzy, c++-format msgid "" "WARNING: Number of toroidal points should be 2^n for efficient FFT " @@ -973,27 +980,27 @@ msgstr "" "WARNING: el número de puntos toroidales debería ser 2^n para una FFT " "eficiente -- considere cambiar MZ si se usan FFTs\n" -#: ../src/mesh/coordinates.cxx:633 +#: ../src/mesh/coordinates.cxx:635 msgid "WARNING: extrapolating input mesh quantities into x-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:410 +#: ../src/mesh/coordinates.cxx:412 msgid "" "WARNING: extrapolating input mesh quantities into x-boundary cells. Set " "option extrapolate_x=false to disable this.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:638 +#: ../src/mesh/coordinates.cxx:640 msgid "WARNING: extrapolating input mesh quantities into y-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:415 +#: ../src/mesh/coordinates.cxx:417 msgid "" "WARNING: extrapolating input mesh quantities into y-boundary cells. Set " "option extrapolate_y=false to disable this.\n" msgstr "" -#: ../src/bout++.cxx:814 +#: ../src/bout++.cxx:825 msgid "Wall time limit in hours. By default (< 0), no limit" msgstr "" @@ -1003,10 +1010,18 @@ msgid "Writing options to file {:s}\n" msgstr "Escribiendo opciones a archivo {:s}\n" #. / The source label given to default values -#: ../src/sys/options.cxx:15 +#: ../src/sys/options.cxx:34 msgid "default" msgstr "por defecto" +#, fuzzy, c++-format +#~ msgid "\tOpenMP parallelisation {}" +#~ msgstr "\tParalelización en OpenMP desactivada\n" + +#, fuzzy, c++-format +#~ msgid "\tOption '{:s}': Boolean expected. Got '{:s}'\n" +#~ msgstr "\tOpción '{:s}': valor Booleano esperado. Se obtuvo '{:s}'\n" + #~ msgid "\tChecking disabled\n" #~ msgstr "\tComprobación desactivada\n" @@ -1014,11 +1029,6 @@ msgstr "por defecto" #~ msgid "\tChecking enabled, level {:d}\n" #~ msgstr "\tComprobación activada, nivel {:d}\n" -#, fuzzy -#~ msgid "\tOpenMP parallelisation enabled, using {:d} threads\n" -#~ msgstr "" -#~ "\tParalelización en OpenMP activada, usando {:d} procesos (`threads`)\n" - #~ msgid "\tSignal handling enabled\n" #~ msgstr "\tGestión de señal activada\n" diff --git a/locale/fr/libbout.po b/locale/fr/libbout.po index ae88b8953c..e9b5476696 100644 --- a/locale/fr/libbout.po +++ b/locale/fr/libbout.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: BOUT++ 4.2.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-09-12 09:17+0100\n" +"POT-Creation-Date: 2025-08-13 23:37+0100\n" "PO-Revision-Date: 2018-10-21 22:46+0100\n" "Last-Translator: \n" "Language-Team: French\n" @@ -17,65 +17,70 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:191 +#: ../src/mesh/impls/bout/boutmesh.cxx:182 #, c++-format msgid "" "\t -> Core region jyseps2_1-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:224 +#: ../src/mesh/impls/bout/boutmesh.cxx:215 #, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:199 +#: ../src/mesh/impls/bout/boutmesh.cxx:190 #, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_2 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:309 +#: ../src/mesh/impls/bout/boutmesh.cxx:300 msgid "\t -> Good value\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:180 +#: ../src/mesh/impls/bout/boutmesh.cxx:171 #, c++-format msgid "" "\t -> Leg region jyseps1_1+1 ({:d}) must be a multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:215 +#: ../src/mesh/impls/bout/boutmesh.cxx:206 #, c++-format msgid "" "\t -> leg region jyseps1_2-ny_inner+1 ({:d}-{:d}+1 = {:d}) must be a " "multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:232 +#: ../src/mesh/impls/bout/boutmesh.cxx:223 #, c++-format msgid "" "\t -> leg region ny-jyseps2_2-1 ({:d}-{:d}-1 = {:d}) must be a multiple of " "MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:208 +#: ../src/mesh/impls/bout/boutmesh.cxx:199 #, c++-format msgid "" "\t -> leg region ny_inner-jyseps2_1-1 ({:d}-{:d}-1 = {:d}) must be a " "multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:175 +#: ../src/mesh/impls/bout/boutmesh.cxx:166 #, c++-format msgid "\t -> ny/NYPE ({:d}/{:d} = {:d}) must be >= MYG ({:d})\n" msgstr "" #: ../src/bout++.cxx:575 #, c++-format +msgid "\tADIOS2 support {}\n" +msgstr "" + +#: ../src/bout++.cxx:583 +#, c++-format msgid "\tBacktrace in exceptions {}\n" msgstr "" @@ -83,40 +88,40 @@ msgstr "" #. Processors divide equally #. Mesh in X divides equally #. Mesh in Y divides equally -#: ../src/mesh/impls/bout/boutmesh.cxx:297 +#: ../src/mesh/impls/bout/boutmesh.cxx:288 #, c++-format msgid "\tCandidate value: {:d}\n" msgstr "" -#: ../src/bout++.cxx:576 +#: ../src/bout++.cxx:584 #, c++-format msgid "\tColour in logs {}\n" msgstr "" -#: ../src/bout++.cxx:594 +#: ../src/bout++.cxx:599 msgid "\tCommand line options for this run : " msgstr "" #. The stringify is needed here as BOUT_FLAGS_STRING may already contain quoted strings #. which could cause problems (e.g. terminate strings). -#: ../src/bout++.cxx:590 +#: ../src/bout++.cxx:595 #, c++-format msgid "\tCompiled with flags : {:s}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:324 +#: ../src/mesh/impls/bout/boutmesh.cxx:315 #, c++-format msgid "" "\tDomain split (NXPE={:d}, NYPE={:d}) into domains (localNx={:d}, " "localNy={:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:364 +#: ../src/mesh/impls/bout/boutmesh.cxx:357 #, c++-format msgid "\tERROR: Cannot split {:d} Y points equally between {:d} processors\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:372 +#: ../src/mesh/impls/bout/boutmesh.cxx:365 #, c++-format msgid "\tERROR: Cannot split {:d} Z points equally between {:d} processors\n" msgstr "" @@ -133,31 +138,31 @@ msgstr "" msgid "\tEmpty key or value in command line '{:s}'\n" msgstr "" -#: ../src/bout++.cxx:582 +#: ../src/bout++.cxx:587 #, c++-format msgid "\tExtra debug output {}\n" msgstr "" -#: ../src/bout++.cxx:561 +#: ../src/bout++.cxx:568 #, c++-format msgid "\tFFT support {}\n" msgstr "" -#: ../src/bout++.cxx:585 +#: ../src/bout++.cxx:590 #, c++-format msgid "\tField name tracking {}\n" msgstr "" -#: ../src/bout++.cxx:583 +#: ../src/bout++.cxx:588 #, c++-format msgid "\tFloating-point exceptions {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:440 +#: ../src/mesh/impls/bout/boutmesh.cxx:476 msgid "\tGrid size: " msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:463 +#: ../src/mesh/impls/bout/boutmesh.cxx:499 msgid "\tGuard cells (x,y,z): " msgstr "" @@ -168,17 +173,17 @@ msgid "" "\tLine: {:s}" msgstr "" -#: ../src/bout++.cxx:563 +#: ../src/bout++.cxx:570 #, c++-format msgid "\tLAPACK support {}\n" msgstr "" -#: ../src/bout++.cxx:586 +#: ../src/bout++.cxx:591 #, c++-format msgid "\tMessage stack {}\n" msgstr "" -#: ../src/bout++.cxx:560 +#: ../src/bout++.cxx:567 #, c++-format msgid "\tMetrics mode is {}\n" msgstr "" @@ -188,35 +193,31 @@ msgstr "" msgid "\tMultiple '=' in command-line argument '{:s}'\n" msgstr "" -#: ../src/bout++.cxx:562 +#: ../src/bout++.cxx:569 #, c++-format msgid "\tNatural language support {}\n" msgstr "" -#: ../src/bout++.cxx:567 +#: ../src/bout++.cxx:574 #, c++-format msgid "\tNetCDF support {}{}\n" msgstr "" -#: ../src/bout++.cxx:577 +#: ../src/bout++.cxx:585 #, c++-format -msgid "\tOpenMP parallelisation {}" +msgid "\tOpenMP parallelisation {}, using {} threads\n" msgstr "" #. Mark the option as used #. Option not found -#: ../src/sys/options.cxx:311 ../src/sys/options.cxx:380 -#: ../src/sys/options.cxx:415 ../src/sys/options.cxx:457 -#: ../src/sys/options.cxx:717 ../src/sys/options.cxx:744 -#: ../src/sys/options.cxx:771 ../include/bout/options.hxx:516 -#: ../include/bout/options.hxx:549 ../include/bout/options.hxx:573 -#: ../include/bout/options.hxx:820 +#: ../include/bout/options.hxx:586 ../include/bout/options.hxx:619 +#: ../include/bout/options.hxx:643 ../include/bout/options.hxx:896 msgid "\tOption " msgstr "" -#: ../src/sys/options.cxx:447 +#: ../src/sys/options.cxx:369 #, c++-format -msgid "\tOption '{:s}': Boolean expected. Got '{:s}'\n" +msgid "\tOption {} = {}" msgstr "" #: ../src/sys/options/options_ini.cxx:70 @@ -224,62 +225,62 @@ msgstr "" msgid "\tOptions file '{:s}' not found\n" msgstr "" -#: ../src/bout++.cxx:568 +#: ../src/bout++.cxx:576 #, c++-format msgid "\tPETSc support {}\n" msgstr "" -#: ../src/bout++.cxx:571 +#: ../src/bout++.cxx:579 #, c++-format msgid "\tPVODE support {}\n" msgstr "" -#: ../src/bout++.cxx:557 +#: ../src/bout++.cxx:564 msgid "\tParallel NetCDF support disabled\n" msgstr "" -#: ../src/bout++.cxx:555 +#: ../src/bout++.cxx:562 msgid "\tParallel NetCDF support enabled\n" msgstr "" -#: ../src/bout++.cxx:569 +#: ../src/bout++.cxx:577 #, c++-format msgid "\tPretty function name support {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:437 +#: ../src/mesh/impls/bout/boutmesh.cxx:473 msgid "\tRead nz from input grid file\n" msgstr "" -#: ../src/mesh/mesh.cxx:238 +#: ../src/mesh/mesh.cxx:249 msgid "\tReading contravariant vector " msgstr "" -#: ../src/mesh/mesh.cxx:231 ../src/mesh/mesh.cxx:252 +#: ../src/mesh/mesh.cxx:242 ../src/mesh/mesh.cxx:263 msgid "\tReading covariant vector " msgstr "" -#: ../src/bout++.cxx:548 +#: ../src/bout++.cxx:555 #, c++-format msgid "\tRuntime error checking {}" msgstr "" -#: ../src/bout++.cxx:573 +#: ../src/bout++.cxx:581 #, c++-format msgid "\tSLEPc support {}\n" msgstr "" -#: ../src/bout++.cxx:574 +#: ../src/bout++.cxx:582 #, c++-format msgid "\tSUNDIALS support {}\n" msgstr "" -#: ../src/bout++.cxx:572 +#: ../src/bout++.cxx:580 #, c++-format msgid "\tScore-P support {}\n" msgstr "" -#: ../src/bout++.cxx:584 +#: ../src/bout++.cxx:589 #, fuzzy, c++-format msgid "\tSignal handling support {}\n" msgstr "\tTraitement du signal désactivé\n" @@ -289,7 +290,7 @@ msgstr "\tTraitement du signal désactivé\n" msgid "\tUsing a timestep {:e}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:577 +#: ../src/mesh/impls/bout/boutmesh.cxx:613 msgid "\tdone\n" msgstr "" @@ -299,7 +300,7 @@ msgid "" "\tSplit Runge-Kutta-Legendre and SSP-RK3 solver\n" msgstr "" -#: ../src/bout++.cxx:371 +#: ../src/bout++.cxx:378 msgid "" "\n" " -d \t\tLook in for input/output files\n" @@ -310,7 +311,7 @@ msgid "" " -q, --quiet\t\t\tDecrease verbosity\n" msgstr "" -#: ../src/sys/expressionparser.cxx:302 +#: ../src/sys/expressionparser.cxx:341 #, c++-format msgid "" "\n" @@ -318,7 +319,7 @@ msgid "" " Did you mean '{0}'?" msgstr "" -#: ../src/solver/solver.cxx:580 +#: ../src/solver/solver.cxx:586 #, fuzzy, c++-format msgid "" "\n" @@ -327,7 +328,7 @@ msgstr "" "\n" "L'exécution se termine à {:s}\n" -#: ../src/solver/solver.cxx:532 +#: ../src/solver/solver.cxx:540 #, fuzzy, c++-format msgid "" "\n" @@ -339,7 +340,7 @@ msgstr "" #. Raw string to help with the formatting of the message, and a #. separate variable so clang-format doesn't barf on the #. exception -#: ../src/sys/options.cxx:1102 +#: ../src/sys/options.cxx:1158 msgid "" "\n" "There were unused input options:\n" @@ -367,7 +368,7 @@ msgid "" "{}" msgstr "" -#: ../src/bout++.cxx:382 +#: ../src/bout++.cxx:389 #, c++-format msgid "" " --print-config\t\tPrint the compile-time configuration\n" @@ -400,55 +401,55 @@ msgid "" "model source (e.g. {:s}.cxx)\n" msgstr "" -#: ../src/bout++.cxx:379 +#: ../src/bout++.cxx:386 msgid " -c, --color\t\t\tColor output using bout-log-color\n" msgstr "" -#: ../include/bout/options.hxx:823 +#: ../include/bout/options.hxx:899 msgid ") overwritten with:" msgstr "" -#: ../src/bout++.cxx:550 +#: ../src/bout++.cxx:557 #, c++-format msgid ", level {}" msgstr "" -#: ../src/bout++.cxx:579 -#, c++-format -msgid ", using {} threads" -msgstr "" - #: ../tests/unit/src/test_bout++.cxx:352 msgid "4 of 8" msgstr "" -#: ../src/sys/options.cxx:868 +#: ../src/sys/options.cxx:895 msgid "All options used\n" msgstr "" -#: ../src/bout++.cxx:528 +#: ../src/bout++.cxx:535 #, c++-format msgid "BOUT++ version {:s}\n" msgstr "" -#: ../src/bout++.cxx:143 +#: ../src/bout++.cxx:147 msgid "Bad command line arguments:\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:559 +#: ../src/sys/expressionparser.cxx:192 +#, c++-format +msgid "Boolean operator argument {:e} is not a bool" +msgstr "" + +#: ../src/mesh/impls/bout/boutmesh.cxx:595 msgid "Boundary regions in this processor: " msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:355 +#: ../src/mesh/impls/bout/boutmesh.cxx:348 #, c++-format msgid "Cannot split {:d} X points equally between {:d} processors\n" msgstr "" -#: ../src/bout++.cxx:818 +#: ../src/bout++.cxx:829 msgid "Check if a file exists, and exit if it does." msgstr "" -#: ../src/bout++.cxx:533 +#: ../src/bout++.cxx:540 #, fuzzy, c++-format msgid "" "Code compiled on {:s} at {:s}\n" @@ -461,7 +462,7 @@ msgstr "" msgid "Command line" msgstr "" -#: ../src/bout++.cxx:544 ../tests/unit/src/test_bout++.cxx:358 +#: ../src/bout++.cxx:551 ../tests/unit/src/test_bout++.cxx:358 msgid "Compile-time options:\n" msgstr "" @@ -469,16 +470,16 @@ msgstr "" msgid "Compiled with flags" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:568 +#: ../src/mesh/impls/bout/boutmesh.cxx:604 msgid "Constructing default regions" msgstr "" -#: ../src/bout++.cxx:520 +#: ../src/bout++.cxx:527 #, c++-format msgid "Could not create PID file {:s}" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:318 +#: ../src/mesh/impls/bout/boutmesh.cxx:309 msgid "" "Could not find a valid value for NXPE. Try a different number of processors." msgstr "" @@ -488,28 +489,28 @@ msgstr "" msgid "Could not open output file '{:s}'\n" msgstr "" -#: ../src/bout++.cxx:652 +#: ../src/bout++.cxx:657 #, c++-format msgid "Could not open {:s}/{:s}.{:d} for writing" msgstr "" #. Error reading -#: ../src/mesh/mesh.cxx:532 +#: ../src/mesh/mesh.cxx:543 #, c++-format msgid "Could not read integer array '{:s}'\n" msgstr "" #. Failed . Probably not important enough to stop the simulation -#: ../src/bout++.cxx:632 +#: ../src/bout++.cxx:637 msgid "Could not run bout-log-color. Make sure it is in your PATH\n" msgstr "" -#: ../src/solver/solver.cxx:765 +#: ../src/solver/solver.cxx:772 #, c++-format msgid "Couldn't add Monitor: {:g} is not a multiple of {:g}!" msgstr "" -#: ../src/sys/expressionparser.cxx:273 +#: ../src/sys/expressionparser.cxx:312 #, c++-format msgid "" "Couldn't find generator '{}'. BOUT++ expressions are now case-sensitive, so " @@ -518,70 +519,70 @@ msgid "" "{}" msgstr "" -#: ../src/mesh/mesh.cxx:568 +#: ../src/mesh/mesh.cxx:587 #, c++-format msgid "Couldn't find region {:s} in regionMap2D" msgstr "" -#: ../src/mesh/mesh.cxx:560 +#: ../src/mesh/mesh.cxx:571 ../src/mesh/mesh.cxx:579 #, c++-format msgid "Couldn't find region {:s} in regionMap3D" msgstr "" -#: ../src/mesh/mesh.cxx:576 +#: ../src/mesh/mesh.cxx:595 #, c++-format msgid "Couldn't find region {:s} in regionMapPerp" msgstr "" #. Convert any exceptions to something a bit more useful -#: ../src/sys/options.cxx:336 +#: ../src/sys/options.cxx:361 #, c++-format msgid "Couldn't get {} from option {:s} = '{:s}': {}" msgstr "" -#: ../src/bout++.cxx:508 +#: ../src/bout++.cxx:515 #, fuzzy, c++-format msgid "DataDir \"{:s}\" does not exist or is not accessible\n" msgstr "" "Le répertoire de données \"{:s}\" n'existe pas ou n'est pas accessible\n" -#: ../src/bout++.cxx:505 +#: ../src/bout++.cxx:512 #, fuzzy, c++-format msgid "DataDir \"{:s}\" is not a directory\n" msgstr "\"{:s}\" n'est pas un répertoire\n" -#: ../src/solver/solver.cxx:665 +#: ../src/solver/solver.cxx:671 msgid "ERROR: Solver is already initialised\n" msgstr "" -#: ../src/bout++.cxx:209 +#: ../src/bout++.cxx:216 #, fuzzy, c++-format msgid "Error encountered during initialisation: {:s}\n" msgstr "Erreur rencontrée lors de l'initialisation : {:s}\n" -#: ../src/bout++.cxx:744 +#: ../src/bout++.cxx:751 msgid "Error whilst writing settings" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:332 +#: ../src/mesh/impls/bout/boutmesh.cxx:323 #, c++-format msgid "Error: nx must be greater than 2 times MXG (2 * {:d})" msgstr "" -#: ../src/solver/solver.cxx:512 +#: ../src/solver/solver.cxx:520 msgid "Failed to initialise solver-> Aborting\n" msgstr "Échec d'initialisation du solutionneur -> Abandonner\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:290 +#: ../src/mesh/impls/bout/boutmesh.cxx:281 #, c++-format msgid "Finding value for NXPE (ideal = {:f})\n" msgstr "" -#: ../src/solver/solver.cxx:668 +#: ../src/solver/solver.cxx:674 msgid "Initialising solver\n" msgstr "" -#: ../src/bout++.cxx:494 +#: ../src/bout++.cxx:501 msgid "" "Input and output file for settings must be different.\n" "Provide -o to avoid this issue.\n" @@ -591,122 +592,122 @@ msgstr "" msgid "Invalid command line option '-' found - maybe check whitespace?" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:400 +#: ../src/mesh/impls/bout/boutmesh.cxx:436 msgid "Loading mesh" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:415 +#: ../src/mesh/impls/bout/boutmesh.cxx:451 msgid "Mesh must contain nx" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:419 +#: ../src/mesh/impls/bout/boutmesh.cxx:455 msgid "Mesh must contain ny" msgstr "" #. Not found -#: ../src/mesh/mesh.cxx:536 +#: ../src/mesh/mesh.cxx:547 #, c++-format msgid "Missing integer array {:s}\n" msgstr "" -#: ../src/solver/solver.cxx:905 +#: ../src/solver/solver.cxx:911 #, c++-format msgid "Monitor signalled to quit (exception {})\n" msgstr "" -#: ../src/solver/solver.cxx:883 +#: ../src/solver/solver.cxx:889 #, c++-format msgid "Monitor signalled to quit (return code {})" msgstr "" -#: ../src/bout++.cxx:823 +#: ../src/bout++.cxx:834 msgid "Name of file whose existence triggers a stop" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:565 +#: ../src/mesh/impls/bout/boutmesh.cxx:601 msgid "No boundary regions in this processor" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:550 +#: ../src/mesh/impls/bout/boutmesh.cxx:586 msgid "No boundary regions; domain is periodic\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:254 +#: ../src/mesh/impls/bout/boutmesh.cxx:245 #, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in x direction ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:267 +#: ../src/mesh/impls/bout/boutmesh.cxx:258 #, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in y direction ({:d})\n" msgstr "" #. Less than 2 time-steps left -#: ../src/bout++.cxx:896 +#: ../src/bout++.cxx:908 #, c++-format msgid "Only {:e} seconds ({:.2f} steps) left. Quitting\n" msgstr "" -#: ../src/sys/options.cxx:303 ../src/sys/options.cxx:345 -#: ../src/sys/options.cxx:393 ../src/sys/options.cxx:428 -#: ../src/sys/options.cxx:703 ../src/sys/options.cxx:730 -#: ../src/sys/options.cxx:757 +#: ../src/sys/options.cxx:382 ../src/sys/options.cxx:398 +#: ../src/sys/options.cxx:441 ../src/sys/options.cxx:471 +#: ../src/sys/options.cxx:745 ../src/sys/options.cxx:767 +#: ../src/sys/options.cxx:789 #, c++-format msgid "Option {:s} has no value" msgstr "" #. Doesn't exist -#: ../src/sys/options.cxx:159 +#: ../src/sys/options.cxx:172 #, c++-format msgid "Option {:s}:{:s} does not exist" msgstr "" -#: ../include/bout/options.hxx:828 +#: ../include/bout/options.hxx:904 #, c++-format msgid "" "Options: Setting a value from same source ({:s}) to new value '{:s}' - old " "value was '{:s}'." msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:552 +#: ../src/mesh/impls/bout/boutmesh.cxx:588 msgid "Possible boundary regions are: " msgstr "" -#: ../src/bout++.cxx:538 +#: ../src/bout++.cxx:545 #, c++-format msgid "" "Processor number: {:d} of {:d}\n" "\n" msgstr "" -#: ../src/mesh/mesh.cxx:609 +#: ../src/mesh/mesh.cxx:642 #, c++-format msgid "Registered region 2D {:s}" msgstr "" -#: ../src/mesh/mesh.cxx:599 +#: ../src/mesh/mesh.cxx:632 #, c++-format msgid "Registered region 3D {:s}" msgstr "" -#: ../src/mesh/mesh.cxx:619 +#: ../src/mesh/mesh.cxx:652 #, c++-format msgid "Registered region Perp {:s}" msgstr "" -#: ../src/bout++.cxx:529 +#: ../src/bout++.cxx:536 #, c++-format msgid "Revision: {:s}\n" msgstr "" -#: ../src/solver/solver.cxx:581 +#: ../src/solver/solver.cxx:587 msgid "Run time : " msgstr "Temps d'exécution : " #. / Run the solver -#: ../src/solver/solver.cxx:525 +#: ../src/solver/solver.cxx:533 msgid "" "Running simulation\n" "\n" @@ -718,66 +719,66 @@ msgstr "" msgid "Signal" msgstr "" -#: ../src/bout++.cxx:865 +#: ../src/bout++.cxx:876 msgid "" "Sim Time | RHS evals | Wall Time | Calc Inv Comm I/O SOLVER\n" "\n" msgstr "" -#: ../src/bout++.cxx:868 +#: ../src/bout++.cxx:879 msgid "" "Sim Time | RHS_e evals | RHS_I evals | Wall Time | Calc Inv " "Comm I/O SOLVER\n" "\n" msgstr "" -#: ../src/solver/solver.cxx:506 +#: ../src/solver/solver.cxx:514 #, fuzzy, c++-format msgid "Solver running for {:d} outputs with monitor timestep of {:e}\n" msgstr "" "Le solveur fonctionne pour {:d} sorties avec un temps de moniteur de {:e}\n" -#: ../src/solver/solver.cxx:502 +#: ../src/solver/solver.cxx:510 #, fuzzy, c++-format msgid "Solver running for {:d} outputs with output timestep of {:e}\n" msgstr "" "Le solveur fonctionne pour {:d} sorties avec un pas de sortie de {:e}\n" -#: ../src/solver/solver.cxx:781 +#: ../src/solver/solver.cxx:788 #, c++-format msgid "" "Solver::addMonitor: Cannot reduce timestep (from {:g} to {:g}) after init is " "called!" msgstr "" -#: ../src/solver/solver.cxx:1281 +#: ../src/solver/solver.cxx:1289 #, c++-format msgid "" "Time derivative at wrong location - Field is at {:s}, derivative is at {:s} " "for field '{:s}'\n" msgstr "" -#: ../src/solver/solver.cxx:1480 +#: ../src/solver/solver.cxx:1494 #, c++-format msgid "Time derivative for variable '{:s}' not set" msgstr "" -#: ../src/mesh/mesh.cxx:605 +#: ../src/mesh/mesh.cxx:638 #, c++-format msgid "Trying to add an already existing region {:s} to regionMap2D" msgstr "" -#: ../src/mesh/mesh.cxx:595 +#: ../src/mesh/mesh.cxx:614 #, c++-format msgid "Trying to add an already existing region {:s} to regionMap3D" msgstr "" -#: ../src/mesh/mesh.cxx:616 +#: ../src/mesh/mesh.cxx:649 #, c++-format msgid "Trying to add an already existing region {:s} to regionMapPerp" msgstr "" -#: ../src/sys/options.cxx:99 ../src/sys/options.cxx:138 +#: ../src/sys/options.cxx:112 ../src/sys/options.cxx:151 #, c++-format msgid "" "Trying to index Option '{0}' with '{1}', but '{0}' is a value, not a " @@ -786,37 +787,37 @@ msgid "" "rename one of them.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:1462 +#: ../src/mesh/coordinates.cxx:1464 msgid "" "Unrecognised paralleltransform option.\n" "Valid choices are 'identity', 'shifted', 'fci'" msgstr "" -#: ../src/sys/options.cxx:872 +#: ../src/sys/options.cxx:899 msgid "Unused options:\n" msgstr "" -#: ../src/bout++.cxx:439 +#: ../src/bout++.cxx:446 #, c++-format msgid "Usage is {:s} -d \n" msgstr "" -#: ../src/bout++.cxx:448 +#: ../src/bout++.cxx:455 #, c++-format msgid "Usage is {:s} -f \n" msgstr "" -#: ../src/bout++.cxx:466 +#: ../src/bout++.cxx:473 #, c++-format msgid "Usage is {:s} -l \n" msgstr "" -#: ../src/bout++.cxx:457 +#: ../src/bout++.cxx:464 #, c++-format msgid "Usage is {:s} -o \n" msgstr "" -#: ../src/bout++.cxx:353 +#: ../src/bout++.cxx:360 #, c++-format msgid "Usage is {} {} \n" msgstr "" @@ -827,7 +828,7 @@ msgstr "" #. Print help message -- note this will be displayed once per processor as we've not #. started MPI yet. -#: ../src/bout++.cxx:367 +#: ../src/bout++.cxx:374 #, c++-format msgid "" "Usage: {:s} [-d ] [-f ] [restart [append]] " @@ -835,94 +836,99 @@ msgid "" msgstr "" #. restart file should be written by physics model -#: ../src/solver/solver.cxx:921 +#: ../src/solver/solver.cxx:927 msgid "User signalled to quit. Returning\n" msgstr "" -#: ../src/sys/options.cxx:373 +#: ../src/sys/options.cxx:486 +#, fuzzy, c++-format +msgid "Value for option {:s} = {:e} is not a bool" +msgstr "\"{:s}\" n'est pas un répertoire\n" + +#: ../src/sys/options.cxx:426 #, c++-format msgid "Value for option {:s} = {:e} is not an integer" msgstr "" -#: ../src/sys/options.cxx:408 +#: ../src/sys/options.cxx:456 #, c++-format msgid "Value for option {:s} cannot be converted to a BoutReal" msgstr "" -#: ../src/sys/options.cxx:581 +#: ../src/sys/options.cxx:623 #, c++-format msgid "Value for option {:s} cannot be converted to a Field2D" msgstr "" -#: ../src/sys/options.cxx:529 +#: ../src/sys/options.cxx:571 #, c++-format msgid "Value for option {:s} cannot be converted to a Field3D" msgstr "" -#: ../src/sys/options.cxx:663 +#: ../src/sys/options.cxx:705 #, c++-format msgid "Value for option {:s} cannot be converted to a FieldPerp" msgstr "" -#: ../src/sys/options.cxx:451 +#: ../src/sys/options.cxx:491 #, c++-format msgid "Value for option {:s} cannot be converted to a bool" msgstr "" -#: ../src/sys/options.cxx:709 +#: ../src/sys/options.cxx:751 #, c++-format msgid "Value for option {:s} cannot be converted to an Array" msgstr "" -#: ../src/sys/options.cxx:736 +#: ../src/sys/options.cxx:773 #, c++-format msgid "Value for option {:s} cannot be converted to an Matrix" msgstr "" -#: ../src/sys/options.cxx:763 +#: ../src/sys/options.cxx:795 #, c++-format msgid "Value for option {:s} cannot be converted to an Tensor" msgstr "" #. Another type which can't be converted -#: ../src/sys/options.cxx:365 +#: ../src/sys/options.cxx:418 #, c++-format msgid "Value for option {:s} is not an integer" msgstr "" -#: ../src/solver/solver.cxx:1232 ../src/solver/solver.cxx:1238 +#: ../src/solver/solver.cxx:1240 ../src/solver/solver.cxx:1246 #, c++-format msgid "Variable '{:s}' not initialised" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:431 +#: ../src/mesh/impls/bout/boutmesh.cxx:467 #, c++-format msgid "" "WARNING: Number of toroidal points should be 2^n for efficient FFT " "performance -- consider changing MZ ({:d}) if using FFTs\n" msgstr "" -#: ../src/mesh/coordinates.cxx:633 +#: ../src/mesh/coordinates.cxx:635 msgid "WARNING: extrapolating input mesh quantities into x-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:410 +#: ../src/mesh/coordinates.cxx:412 msgid "" "WARNING: extrapolating input mesh quantities into x-boundary cells. Set " "option extrapolate_x=false to disable this.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:638 +#: ../src/mesh/coordinates.cxx:640 msgid "WARNING: extrapolating input mesh quantities into y-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:415 +#: ../src/mesh/coordinates.cxx:417 msgid "" "WARNING: extrapolating input mesh quantities into y-boundary cells. Set " "option extrapolate_y=false to disable this.\n" msgstr "" -#: ../src/bout++.cxx:814 +#: ../src/bout++.cxx:825 msgid "Wall time limit in hours. By default (< 0), no limit" msgstr "" @@ -932,7 +938,7 @@ msgid "Writing options to file {:s}\n" msgstr "" #. / The source label given to default values -#: ../src/sys/options.cxx:15 +#: ../src/sys/options.cxx:34 msgid "default" msgstr "" @@ -946,10 +952,6 @@ msgstr "" #~ msgid "\tSignal handling enabled\n" #~ msgstr "\tTraitement du signal activé\n" -#, fuzzy -#~ msgid "Option {:s} is not a section" -#~ msgstr "\"{:s}\" n'est pas un répertoire\n" - #, fuzzy #~ msgid "Error encountered during initialisation\n" #~ msgstr "Erreur rencontrée lors de l'initialisation\n" diff --git a/locale/libbout.pot b/locale/libbout.pot index 3895001ba0..2ef0618dd0 100644 --- a/locale/libbout.pot +++ b/locale/libbout.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-09-12 09:17+0100\n" +"POT-Creation-Date: 2025-08-13 23:37+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,65 +17,70 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:191 +#: ../src/mesh/impls/bout/boutmesh.cxx:182 #, c++-format msgid "" "\t -> Core region jyseps2_1-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:224 +#: ../src/mesh/impls/bout/boutmesh.cxx:215 #, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:199 +#: ../src/mesh/impls/bout/boutmesh.cxx:190 #, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_2 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:309 +#: ../src/mesh/impls/bout/boutmesh.cxx:300 msgid "\t -> Good value\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:180 +#: ../src/mesh/impls/bout/boutmesh.cxx:171 #, c++-format msgid "" "\t -> Leg region jyseps1_1+1 ({:d}) must be a multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:215 +#: ../src/mesh/impls/bout/boutmesh.cxx:206 #, c++-format msgid "" "\t -> leg region jyseps1_2-ny_inner+1 ({:d}-{:d}+1 = {:d}) must be a " "multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:232 +#: ../src/mesh/impls/bout/boutmesh.cxx:223 #, c++-format msgid "" "\t -> leg region ny-jyseps2_2-1 ({:d}-{:d}-1 = {:d}) must be a multiple of " "MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:208 +#: ../src/mesh/impls/bout/boutmesh.cxx:199 #, c++-format msgid "" "\t -> leg region ny_inner-jyseps2_1-1 ({:d}-{:d}-1 = {:d}) must be a " "multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:175 +#: ../src/mesh/impls/bout/boutmesh.cxx:166 #, c++-format msgid "\t -> ny/NYPE ({:d}/{:d} = {:d}) must be >= MYG ({:d})\n" msgstr "" #: ../src/bout++.cxx:575 #, c++-format +msgid "\tADIOS2 support {}\n" +msgstr "" + +#: ../src/bout++.cxx:583 +#, c++-format msgid "\tBacktrace in exceptions {}\n" msgstr "" @@ -83,40 +88,40 @@ msgstr "" #. Processors divide equally #. Mesh in X divides equally #. Mesh in Y divides equally -#: ../src/mesh/impls/bout/boutmesh.cxx:297 +#: ../src/mesh/impls/bout/boutmesh.cxx:288 #, c++-format msgid "\tCandidate value: {:d}\n" msgstr "" -#: ../src/bout++.cxx:576 +#: ../src/bout++.cxx:584 #, c++-format msgid "\tColour in logs {}\n" msgstr "" -#: ../src/bout++.cxx:594 +#: ../src/bout++.cxx:599 msgid "\tCommand line options for this run : " msgstr "" #. The stringify is needed here as BOUT_FLAGS_STRING may already contain quoted strings #. which could cause problems (e.g. terminate strings). -#: ../src/bout++.cxx:590 +#: ../src/bout++.cxx:595 #, c++-format msgid "\tCompiled with flags : {:s}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:324 +#: ../src/mesh/impls/bout/boutmesh.cxx:315 #, c++-format msgid "" "\tDomain split (NXPE={:d}, NYPE={:d}) into domains (localNx={:d}, " "localNy={:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:364 +#: ../src/mesh/impls/bout/boutmesh.cxx:357 #, c++-format msgid "\tERROR: Cannot split {:d} Y points equally between {:d} processors\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:372 +#: ../src/mesh/impls/bout/boutmesh.cxx:365 #, c++-format msgid "\tERROR: Cannot split {:d} Z points equally between {:d} processors\n" msgstr "" @@ -133,31 +138,31 @@ msgstr "" msgid "\tEmpty key or value in command line '{:s}'\n" msgstr "" -#: ../src/bout++.cxx:582 +#: ../src/bout++.cxx:587 #, c++-format msgid "\tExtra debug output {}\n" msgstr "" -#: ../src/bout++.cxx:561 +#: ../src/bout++.cxx:568 #, c++-format msgid "\tFFT support {}\n" msgstr "" -#: ../src/bout++.cxx:585 +#: ../src/bout++.cxx:590 #, c++-format msgid "\tField name tracking {}\n" msgstr "" -#: ../src/bout++.cxx:583 +#: ../src/bout++.cxx:588 #, c++-format msgid "\tFloating-point exceptions {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:440 +#: ../src/mesh/impls/bout/boutmesh.cxx:476 msgid "\tGrid size: " msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:463 +#: ../src/mesh/impls/bout/boutmesh.cxx:499 msgid "\tGuard cells (x,y,z): " msgstr "" @@ -168,17 +173,17 @@ msgid "" "\tLine: {:s}" msgstr "" -#: ../src/bout++.cxx:563 +#: ../src/bout++.cxx:570 #, c++-format msgid "\tLAPACK support {}\n" msgstr "" -#: ../src/bout++.cxx:586 +#: ../src/bout++.cxx:591 #, c++-format msgid "\tMessage stack {}\n" msgstr "" -#: ../src/bout++.cxx:560 +#: ../src/bout++.cxx:567 #, c++-format msgid "\tMetrics mode is {}\n" msgstr "" @@ -188,35 +193,31 @@ msgstr "" msgid "\tMultiple '=' in command-line argument '{:s}'\n" msgstr "" -#: ../src/bout++.cxx:562 +#: ../src/bout++.cxx:569 #, c++-format msgid "\tNatural language support {}\n" msgstr "" -#: ../src/bout++.cxx:567 +#: ../src/bout++.cxx:574 #, c++-format msgid "\tNetCDF support {}{}\n" msgstr "" -#: ../src/bout++.cxx:577 +#: ../src/bout++.cxx:585 #, c++-format -msgid "\tOpenMP parallelisation {}" +msgid "\tOpenMP parallelisation {}, using {} threads\n" msgstr "" #. Mark the option as used #. Option not found -#: ../src/sys/options.cxx:311 ../src/sys/options.cxx:380 -#: ../src/sys/options.cxx:415 ../src/sys/options.cxx:457 -#: ../src/sys/options.cxx:717 ../src/sys/options.cxx:744 -#: ../src/sys/options.cxx:771 ../include/bout/options.hxx:516 -#: ../include/bout/options.hxx:549 ../include/bout/options.hxx:573 -#: ../include/bout/options.hxx:820 +#: ../include/bout/options.hxx:586 ../include/bout/options.hxx:619 +#: ../include/bout/options.hxx:643 ../include/bout/options.hxx:896 msgid "\tOption " msgstr "" -#: ../src/sys/options.cxx:447 +#: ../src/sys/options.cxx:369 #, c++-format -msgid "\tOption '{:s}': Boolean expected. Got '{:s}'\n" +msgid "\tOption {} = {}" msgstr "" #: ../src/sys/options/options_ini.cxx:70 @@ -224,62 +225,62 @@ msgstr "" msgid "\tOptions file '{:s}' not found\n" msgstr "" -#: ../src/bout++.cxx:568 +#: ../src/bout++.cxx:576 #, c++-format msgid "\tPETSc support {}\n" msgstr "" -#: ../src/bout++.cxx:571 +#: ../src/bout++.cxx:579 #, c++-format msgid "\tPVODE support {}\n" msgstr "" -#: ../src/bout++.cxx:557 +#: ../src/bout++.cxx:564 msgid "\tParallel NetCDF support disabled\n" msgstr "" -#: ../src/bout++.cxx:555 +#: ../src/bout++.cxx:562 msgid "\tParallel NetCDF support enabled\n" msgstr "" -#: ../src/bout++.cxx:569 +#: ../src/bout++.cxx:577 #, c++-format msgid "\tPretty function name support {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:437 +#: ../src/mesh/impls/bout/boutmesh.cxx:473 msgid "\tRead nz from input grid file\n" msgstr "" -#: ../src/mesh/mesh.cxx:238 +#: ../src/mesh/mesh.cxx:249 msgid "\tReading contravariant vector " msgstr "" -#: ../src/mesh/mesh.cxx:231 ../src/mesh/mesh.cxx:252 +#: ../src/mesh/mesh.cxx:242 ../src/mesh/mesh.cxx:263 msgid "\tReading covariant vector " msgstr "" -#: ../src/bout++.cxx:548 +#: ../src/bout++.cxx:555 #, c++-format msgid "\tRuntime error checking {}" msgstr "" -#: ../src/bout++.cxx:573 +#: ../src/bout++.cxx:581 #, c++-format msgid "\tSLEPc support {}\n" msgstr "" -#: ../src/bout++.cxx:574 +#: ../src/bout++.cxx:582 #, c++-format msgid "\tSUNDIALS support {}\n" msgstr "" -#: ../src/bout++.cxx:572 +#: ../src/bout++.cxx:580 #, c++-format msgid "\tScore-P support {}\n" msgstr "" -#: ../src/bout++.cxx:584 +#: ../src/bout++.cxx:589 #, c++-format msgid "\tSignal handling support {}\n" msgstr "" @@ -289,7 +290,7 @@ msgstr "" msgid "\tUsing a timestep {:e}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:577 +#: ../src/mesh/impls/bout/boutmesh.cxx:613 msgid "\tdone\n" msgstr "" @@ -299,7 +300,7 @@ msgid "" "\tSplit Runge-Kutta-Legendre and SSP-RK3 solver\n" msgstr "" -#: ../src/bout++.cxx:371 +#: ../src/bout++.cxx:378 msgid "" "\n" " -d \t\tLook in for input/output files\n" @@ -310,7 +311,7 @@ msgid "" " -q, --quiet\t\t\tDecrease verbosity\n" msgstr "" -#: ../src/sys/expressionparser.cxx:302 +#: ../src/sys/expressionparser.cxx:341 #, c++-format msgid "" "\n" @@ -318,14 +319,14 @@ msgid "" " Did you mean '{0}'?" msgstr "" -#: ../src/solver/solver.cxx:580 +#: ../src/solver/solver.cxx:586 #, c++-format msgid "" "\n" "Run finished at : {:s}\n" msgstr "" -#: ../src/solver/solver.cxx:532 +#: ../src/solver/solver.cxx:540 #, c++-format msgid "" "\n" @@ -335,7 +336,7 @@ msgstr "" #. Raw string to help with the formatting of the message, and a #. separate variable so clang-format doesn't barf on the #. exception -#: ../src/sys/options.cxx:1102 +#: ../src/sys/options.cxx:1158 msgid "" "\n" "There were unused input options:\n" @@ -363,7 +364,7 @@ msgid "" "{}" msgstr "" -#: ../src/bout++.cxx:382 +#: ../src/bout++.cxx:389 #, c++-format msgid "" " --print-config\t\tPrint the compile-time configuration\n" @@ -396,55 +397,55 @@ msgid "" "model source (e.g. {:s}.cxx)\n" msgstr "" -#: ../src/bout++.cxx:379 +#: ../src/bout++.cxx:386 msgid " -c, --color\t\t\tColor output using bout-log-color\n" msgstr "" -#: ../include/bout/options.hxx:823 +#: ../include/bout/options.hxx:899 msgid ") overwritten with:" msgstr "" -#: ../src/bout++.cxx:550 +#: ../src/bout++.cxx:557 #, c++-format msgid ", level {}" msgstr "" -#: ../src/bout++.cxx:579 -#, c++-format -msgid ", using {} threads" -msgstr "" - #: ../tests/unit/src/test_bout++.cxx:352 msgid "4 of 8" msgstr "" -#: ../src/sys/options.cxx:868 +#: ../src/sys/options.cxx:895 msgid "All options used\n" msgstr "" -#: ../src/bout++.cxx:528 +#: ../src/bout++.cxx:535 #, c++-format msgid "BOUT++ version {:s}\n" msgstr "" -#: ../src/bout++.cxx:143 +#: ../src/bout++.cxx:147 msgid "Bad command line arguments:\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:559 +#: ../src/sys/expressionparser.cxx:192 +#, c++-format +msgid "Boolean operator argument {:e} is not a bool" +msgstr "" + +#: ../src/mesh/impls/bout/boutmesh.cxx:595 msgid "Boundary regions in this processor: " msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:355 +#: ../src/mesh/impls/bout/boutmesh.cxx:348 #, c++-format msgid "Cannot split {:d} X points equally between {:d} processors\n" msgstr "" -#: ../src/bout++.cxx:818 +#: ../src/bout++.cxx:829 msgid "Check if a file exists, and exit if it does." msgstr "" -#: ../src/bout++.cxx:533 +#: ../src/bout++.cxx:540 #, c++-format msgid "" "Code compiled on {:s} at {:s}\n" @@ -455,7 +456,7 @@ msgstr "" msgid "Command line" msgstr "" -#: ../src/bout++.cxx:544 ../tests/unit/src/test_bout++.cxx:358 +#: ../src/bout++.cxx:551 ../tests/unit/src/test_bout++.cxx:358 msgid "Compile-time options:\n" msgstr "" @@ -463,16 +464,16 @@ msgstr "" msgid "Compiled with flags" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:568 +#: ../src/mesh/impls/bout/boutmesh.cxx:604 msgid "Constructing default regions" msgstr "" -#: ../src/bout++.cxx:520 +#: ../src/bout++.cxx:527 #, c++-format msgid "Could not create PID file {:s}" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:318 +#: ../src/mesh/impls/bout/boutmesh.cxx:309 msgid "" "Could not find a valid value for NXPE. Try a different number of processors." msgstr "" @@ -482,28 +483,28 @@ msgstr "" msgid "Could not open output file '{:s}'\n" msgstr "" -#: ../src/bout++.cxx:652 +#: ../src/bout++.cxx:657 #, c++-format msgid "Could not open {:s}/{:s}.{:d} for writing" msgstr "" #. Error reading -#: ../src/mesh/mesh.cxx:532 +#: ../src/mesh/mesh.cxx:543 #, c++-format msgid "Could not read integer array '{:s}'\n" msgstr "" #. Failed . Probably not important enough to stop the simulation -#: ../src/bout++.cxx:632 +#: ../src/bout++.cxx:637 msgid "Could not run bout-log-color. Make sure it is in your PATH\n" msgstr "" -#: ../src/solver/solver.cxx:765 +#: ../src/solver/solver.cxx:772 #, c++-format msgid "Couldn't add Monitor: {:g} is not a multiple of {:g}!" msgstr "" -#: ../src/sys/expressionparser.cxx:273 +#: ../src/sys/expressionparser.cxx:312 #, c++-format msgid "" "Couldn't find generator '{}'. BOUT++ expressions are now case-sensitive, so " @@ -512,69 +513,69 @@ msgid "" "{}" msgstr "" -#: ../src/mesh/mesh.cxx:568 +#: ../src/mesh/mesh.cxx:587 #, c++-format msgid "Couldn't find region {:s} in regionMap2D" msgstr "" -#: ../src/mesh/mesh.cxx:560 +#: ../src/mesh/mesh.cxx:571 ../src/mesh/mesh.cxx:579 #, c++-format msgid "Couldn't find region {:s} in regionMap3D" msgstr "" -#: ../src/mesh/mesh.cxx:576 +#: ../src/mesh/mesh.cxx:595 #, c++-format msgid "Couldn't find region {:s} in regionMapPerp" msgstr "" #. Convert any exceptions to something a bit more useful -#: ../src/sys/options.cxx:336 +#: ../src/sys/options.cxx:361 #, c++-format msgid "Couldn't get {} from option {:s} = '{:s}': {}" msgstr "" -#: ../src/bout++.cxx:508 +#: ../src/bout++.cxx:515 #, c++-format msgid "DataDir \"{:s}\" does not exist or is not accessible\n" msgstr "" -#: ../src/bout++.cxx:505 +#: ../src/bout++.cxx:512 #, c++-format msgid "DataDir \"{:s}\" is not a directory\n" msgstr "" -#: ../src/solver/solver.cxx:665 +#: ../src/solver/solver.cxx:671 msgid "ERROR: Solver is already initialised\n" msgstr "" -#: ../src/bout++.cxx:209 +#: ../src/bout++.cxx:216 #, c++-format msgid "Error encountered during initialisation: {:s}\n" msgstr "" -#: ../src/bout++.cxx:744 +#: ../src/bout++.cxx:751 msgid "Error whilst writing settings" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:332 +#: ../src/mesh/impls/bout/boutmesh.cxx:323 #, c++-format msgid "Error: nx must be greater than 2 times MXG (2 * {:d})" msgstr "" -#: ../src/solver/solver.cxx:512 +#: ../src/solver/solver.cxx:520 msgid "Failed to initialise solver-> Aborting\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:290 +#: ../src/mesh/impls/bout/boutmesh.cxx:281 #, c++-format msgid "Finding value for NXPE (ideal = {:f})\n" msgstr "" -#: ../src/solver/solver.cxx:668 +#: ../src/solver/solver.cxx:674 msgid "Initialising solver\n" msgstr "" -#: ../src/bout++.cxx:494 +#: ../src/bout++.cxx:501 msgid "" "Input and output file for settings must be different.\n" "Provide -o to avoid this issue.\n" @@ -584,122 +585,122 @@ msgstr "" msgid "Invalid command line option '-' found - maybe check whitespace?" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:400 +#: ../src/mesh/impls/bout/boutmesh.cxx:436 msgid "Loading mesh" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:415 +#: ../src/mesh/impls/bout/boutmesh.cxx:451 msgid "Mesh must contain nx" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:419 +#: ../src/mesh/impls/bout/boutmesh.cxx:455 msgid "Mesh must contain ny" msgstr "" #. Not found -#: ../src/mesh/mesh.cxx:536 +#: ../src/mesh/mesh.cxx:547 #, c++-format msgid "Missing integer array {:s}\n" msgstr "" -#: ../src/solver/solver.cxx:905 +#: ../src/solver/solver.cxx:911 #, c++-format msgid "Monitor signalled to quit (exception {})\n" msgstr "" -#: ../src/solver/solver.cxx:883 +#: ../src/solver/solver.cxx:889 #, c++-format msgid "Monitor signalled to quit (return code {})" msgstr "" -#: ../src/bout++.cxx:823 +#: ../src/bout++.cxx:834 msgid "Name of file whose existence triggers a stop" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:565 +#: ../src/mesh/impls/bout/boutmesh.cxx:601 msgid "No boundary regions in this processor" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:550 +#: ../src/mesh/impls/bout/boutmesh.cxx:586 msgid "No boundary regions; domain is periodic\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:254 +#: ../src/mesh/impls/bout/boutmesh.cxx:245 #, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in x direction ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:267 +#: ../src/mesh/impls/bout/boutmesh.cxx:258 #, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in y direction ({:d})\n" msgstr "" #. Less than 2 time-steps left -#: ../src/bout++.cxx:896 +#: ../src/bout++.cxx:908 #, c++-format msgid "Only {:e} seconds ({:.2f} steps) left. Quitting\n" msgstr "" -#: ../src/sys/options.cxx:303 ../src/sys/options.cxx:345 -#: ../src/sys/options.cxx:393 ../src/sys/options.cxx:428 -#: ../src/sys/options.cxx:703 ../src/sys/options.cxx:730 -#: ../src/sys/options.cxx:757 +#: ../src/sys/options.cxx:382 ../src/sys/options.cxx:398 +#: ../src/sys/options.cxx:441 ../src/sys/options.cxx:471 +#: ../src/sys/options.cxx:745 ../src/sys/options.cxx:767 +#: ../src/sys/options.cxx:789 #, c++-format msgid "Option {:s} has no value" msgstr "" #. Doesn't exist -#: ../src/sys/options.cxx:159 +#: ../src/sys/options.cxx:172 #, c++-format msgid "Option {:s}:{:s} does not exist" msgstr "" -#: ../include/bout/options.hxx:828 +#: ../include/bout/options.hxx:904 #, c++-format msgid "" "Options: Setting a value from same source ({:s}) to new value '{:s}' - old " "value was '{:s}'." msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:552 +#: ../src/mesh/impls/bout/boutmesh.cxx:588 msgid "Possible boundary regions are: " msgstr "" -#: ../src/bout++.cxx:538 +#: ../src/bout++.cxx:545 #, c++-format msgid "" "Processor number: {:d} of {:d}\n" "\n" msgstr "" -#: ../src/mesh/mesh.cxx:609 +#: ../src/mesh/mesh.cxx:642 #, c++-format msgid "Registered region 2D {:s}" msgstr "" -#: ../src/mesh/mesh.cxx:599 +#: ../src/mesh/mesh.cxx:632 #, c++-format msgid "Registered region 3D {:s}" msgstr "" -#: ../src/mesh/mesh.cxx:619 +#: ../src/mesh/mesh.cxx:652 #, c++-format msgid "Registered region Perp {:s}" msgstr "" -#: ../src/bout++.cxx:529 +#: ../src/bout++.cxx:536 #, c++-format msgid "Revision: {:s}\n" msgstr "" -#: ../src/solver/solver.cxx:581 +#: ../src/solver/solver.cxx:587 msgid "Run time : " msgstr "" #. / Run the solver -#: ../src/solver/solver.cxx:525 +#: ../src/solver/solver.cxx:533 msgid "" "Running simulation\n" "\n" @@ -709,64 +710,64 @@ msgstr "" msgid "Signal" msgstr "" -#: ../src/bout++.cxx:865 +#: ../src/bout++.cxx:876 msgid "" "Sim Time | RHS evals | Wall Time | Calc Inv Comm I/O SOLVER\n" "\n" msgstr "" -#: ../src/bout++.cxx:868 +#: ../src/bout++.cxx:879 msgid "" "Sim Time | RHS_e evals | RHS_I evals | Wall Time | Calc Inv " "Comm I/O SOLVER\n" "\n" msgstr "" -#: ../src/solver/solver.cxx:506 +#: ../src/solver/solver.cxx:514 #, c++-format msgid "Solver running for {:d} outputs with monitor timestep of {:e}\n" msgstr "" -#: ../src/solver/solver.cxx:502 +#: ../src/solver/solver.cxx:510 #, c++-format msgid "Solver running for {:d} outputs with output timestep of {:e}\n" msgstr "" -#: ../src/solver/solver.cxx:781 +#: ../src/solver/solver.cxx:788 #, c++-format msgid "" "Solver::addMonitor: Cannot reduce timestep (from {:g} to {:g}) after init is " "called!" msgstr "" -#: ../src/solver/solver.cxx:1281 +#: ../src/solver/solver.cxx:1289 #, c++-format msgid "" "Time derivative at wrong location - Field is at {:s}, derivative is at {:s} " "for field '{:s}'\n" msgstr "" -#: ../src/solver/solver.cxx:1480 +#: ../src/solver/solver.cxx:1494 #, c++-format msgid "Time derivative for variable '{:s}' not set" msgstr "" -#: ../src/mesh/mesh.cxx:605 +#: ../src/mesh/mesh.cxx:638 #, c++-format msgid "Trying to add an already existing region {:s} to regionMap2D" msgstr "" -#: ../src/mesh/mesh.cxx:595 +#: ../src/mesh/mesh.cxx:614 #, c++-format msgid "Trying to add an already existing region {:s} to regionMap3D" msgstr "" -#: ../src/mesh/mesh.cxx:616 +#: ../src/mesh/mesh.cxx:649 #, c++-format msgid "Trying to add an already existing region {:s} to regionMapPerp" msgstr "" -#: ../src/sys/options.cxx:99 ../src/sys/options.cxx:138 +#: ../src/sys/options.cxx:112 ../src/sys/options.cxx:151 #, c++-format msgid "" "Trying to index Option '{0}' with '{1}', but '{0}' is a value, not a " @@ -775,37 +776,37 @@ msgid "" "rename one of them.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:1462 +#: ../src/mesh/coordinates.cxx:1464 msgid "" "Unrecognised paralleltransform option.\n" "Valid choices are 'identity', 'shifted', 'fci'" msgstr "" -#: ../src/sys/options.cxx:872 +#: ../src/sys/options.cxx:899 msgid "Unused options:\n" msgstr "" -#: ../src/bout++.cxx:439 +#: ../src/bout++.cxx:446 #, c++-format msgid "Usage is {:s} -d \n" msgstr "" -#: ../src/bout++.cxx:448 +#: ../src/bout++.cxx:455 #, c++-format msgid "Usage is {:s} -f \n" msgstr "" -#: ../src/bout++.cxx:466 +#: ../src/bout++.cxx:473 #, c++-format msgid "Usage is {:s} -l \n" msgstr "" -#: ../src/bout++.cxx:457 +#: ../src/bout++.cxx:464 #, c++-format msgid "Usage is {:s} -o \n" msgstr "" -#: ../src/bout++.cxx:353 +#: ../src/bout++.cxx:360 #, c++-format msgid "Usage is {} {} \n" msgstr "" @@ -816,7 +817,7 @@ msgstr "" #. Print help message -- note this will be displayed once per processor as we've not #. started MPI yet. -#: ../src/bout++.cxx:367 +#: ../src/bout++.cxx:374 #, c++-format msgid "" "Usage: {:s} [-d ] [-f ] [restart [append]] " @@ -824,94 +825,99 @@ msgid "" msgstr "" #. restart file should be written by physics model -#: ../src/solver/solver.cxx:921 +#: ../src/solver/solver.cxx:927 msgid "User signalled to quit. Returning\n" msgstr "" -#: ../src/sys/options.cxx:373 +#: ../src/sys/options.cxx:486 +#, c++-format +msgid "Value for option {:s} = {:e} is not a bool" +msgstr "" + +#: ../src/sys/options.cxx:426 #, c++-format msgid "Value for option {:s} = {:e} is not an integer" msgstr "" -#: ../src/sys/options.cxx:408 +#: ../src/sys/options.cxx:456 #, c++-format msgid "Value for option {:s} cannot be converted to a BoutReal" msgstr "" -#: ../src/sys/options.cxx:581 +#: ../src/sys/options.cxx:623 #, c++-format msgid "Value for option {:s} cannot be converted to a Field2D" msgstr "" -#: ../src/sys/options.cxx:529 +#: ../src/sys/options.cxx:571 #, c++-format msgid "Value for option {:s} cannot be converted to a Field3D" msgstr "" -#: ../src/sys/options.cxx:663 +#: ../src/sys/options.cxx:705 #, c++-format msgid "Value for option {:s} cannot be converted to a FieldPerp" msgstr "" -#: ../src/sys/options.cxx:451 +#: ../src/sys/options.cxx:491 #, c++-format msgid "Value for option {:s} cannot be converted to a bool" msgstr "" -#: ../src/sys/options.cxx:709 +#: ../src/sys/options.cxx:751 #, c++-format msgid "Value for option {:s} cannot be converted to an Array" msgstr "" -#: ../src/sys/options.cxx:736 +#: ../src/sys/options.cxx:773 #, c++-format msgid "Value for option {:s} cannot be converted to an Matrix" msgstr "" -#: ../src/sys/options.cxx:763 +#: ../src/sys/options.cxx:795 #, c++-format msgid "Value for option {:s} cannot be converted to an Tensor" msgstr "" #. Another type which can't be converted -#: ../src/sys/options.cxx:365 +#: ../src/sys/options.cxx:418 #, c++-format msgid "Value for option {:s} is not an integer" msgstr "" -#: ../src/solver/solver.cxx:1232 ../src/solver/solver.cxx:1238 +#: ../src/solver/solver.cxx:1240 ../src/solver/solver.cxx:1246 #, c++-format msgid "Variable '{:s}' not initialised" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:431 +#: ../src/mesh/impls/bout/boutmesh.cxx:467 #, c++-format msgid "" "WARNING: Number of toroidal points should be 2^n for efficient FFT " "performance -- consider changing MZ ({:d}) if using FFTs\n" msgstr "" -#: ../src/mesh/coordinates.cxx:633 +#: ../src/mesh/coordinates.cxx:635 msgid "WARNING: extrapolating input mesh quantities into x-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:410 +#: ../src/mesh/coordinates.cxx:412 msgid "" "WARNING: extrapolating input mesh quantities into x-boundary cells. Set " "option extrapolate_x=false to disable this.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:638 +#: ../src/mesh/coordinates.cxx:640 msgid "WARNING: extrapolating input mesh quantities into y-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:415 +#: ../src/mesh/coordinates.cxx:417 msgid "" "WARNING: extrapolating input mesh quantities into y-boundary cells. Set " "option extrapolate_y=false to disable this.\n" msgstr "" -#: ../src/bout++.cxx:814 +#: ../src/bout++.cxx:825 msgid "Wall time limit in hours. By default (< 0), no limit" msgstr "" @@ -921,6 +927,6 @@ msgid "Writing options to file {:s}\n" msgstr "" #. / The source label given to default values -#: ../src/sys/options.cxx:15 +#: ../src/sys/options.cxx:34 msgid "default" msgstr "" diff --git a/locale/zh_CN/libbout.po b/locale/zh_CN/libbout.po index 2c53b5392c..ecf8517d62 100644 --- a/locale/zh_CN/libbout.po +++ b/locale/zh_CN/libbout.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: BOUT++ 4.2.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-09-12 09:17+0100\n" +"POT-Creation-Date: 2025-08-13 23:37+0100\n" "PO-Revision-Date: 2018-10-22 22:56+0100\n" "Last-Translator: \n" "Language-Team: Chinese (simplified)\n" @@ -16,65 +16,70 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:191 +#: ../src/mesh/impls/bout/boutmesh.cxx:182 #, c++-format msgid "" "\t -> Core region jyseps2_1-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:224 +#: ../src/mesh/impls/bout/boutmesh.cxx:215 #, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:199 +#: ../src/mesh/impls/bout/boutmesh.cxx:190 #, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_2 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:309 +#: ../src/mesh/impls/bout/boutmesh.cxx:300 msgid "\t -> Good value\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:180 +#: ../src/mesh/impls/bout/boutmesh.cxx:171 #, c++-format msgid "" "\t -> Leg region jyseps1_1+1 ({:d}) must be a multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:215 +#: ../src/mesh/impls/bout/boutmesh.cxx:206 #, c++-format msgid "" "\t -> leg region jyseps1_2-ny_inner+1 ({:d}-{:d}+1 = {:d}) must be a " "multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:232 +#: ../src/mesh/impls/bout/boutmesh.cxx:223 #, c++-format msgid "" "\t -> leg region ny-jyseps2_2-1 ({:d}-{:d}-1 = {:d}) must be a multiple of " "MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:208 +#: ../src/mesh/impls/bout/boutmesh.cxx:199 #, c++-format msgid "" "\t -> leg region ny_inner-jyseps2_1-1 ({:d}-{:d}-1 = {:d}) must be a " "multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:175 +#: ../src/mesh/impls/bout/boutmesh.cxx:166 #, c++-format msgid "\t -> ny/NYPE ({:d}/{:d} = {:d}) must be >= MYG ({:d})\n" msgstr "" #: ../src/bout++.cxx:575 #, c++-format +msgid "\tADIOS2 support {}\n" +msgstr "" + +#: ../src/bout++.cxx:583 +#, c++-format msgid "\tBacktrace in exceptions {}\n" msgstr "" @@ -82,40 +87,40 @@ msgstr "" #. Processors divide equally #. Mesh in X divides equally #. Mesh in Y divides equally -#: ../src/mesh/impls/bout/boutmesh.cxx:297 +#: ../src/mesh/impls/bout/boutmesh.cxx:288 #, c++-format msgid "\tCandidate value: {:d}\n" msgstr "" -#: ../src/bout++.cxx:576 +#: ../src/bout++.cxx:584 #, c++-format msgid "\tColour in logs {}\n" msgstr "" -#: ../src/bout++.cxx:594 +#: ../src/bout++.cxx:599 msgid "\tCommand line options for this run : " msgstr "" #. The stringify is needed here as BOUT_FLAGS_STRING may already contain quoted strings #. which could cause problems (e.g. terminate strings). -#: ../src/bout++.cxx:590 +#: ../src/bout++.cxx:595 #, c++-format msgid "\tCompiled with flags : {:s}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:324 +#: ../src/mesh/impls/bout/boutmesh.cxx:315 #, c++-format msgid "" "\tDomain split (NXPE={:d}, NYPE={:d}) into domains (localNx={:d}, " "localNy={:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:364 +#: ../src/mesh/impls/bout/boutmesh.cxx:357 #, c++-format msgid "\tERROR: Cannot split {:d} Y points equally between {:d} processors\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:372 +#: ../src/mesh/impls/bout/boutmesh.cxx:365 #, c++-format msgid "\tERROR: Cannot split {:d} Z points equally between {:d} processors\n" msgstr "" @@ -132,31 +137,31 @@ msgstr "" msgid "\tEmpty key or value in command line '{:s}'\n" msgstr "" -#: ../src/bout++.cxx:582 +#: ../src/bout++.cxx:587 #, c++-format msgid "\tExtra debug output {}\n" msgstr "" -#: ../src/bout++.cxx:561 +#: ../src/bout++.cxx:568 #, c++-format msgid "\tFFT support {}\n" msgstr "" -#: ../src/bout++.cxx:585 +#: ../src/bout++.cxx:590 #, c++-format msgid "\tField name tracking {}\n" msgstr "" -#: ../src/bout++.cxx:583 +#: ../src/bout++.cxx:588 #, c++-format msgid "\tFloating-point exceptions {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:440 +#: ../src/mesh/impls/bout/boutmesh.cxx:476 msgid "\tGrid size: " msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:463 +#: ../src/mesh/impls/bout/boutmesh.cxx:499 msgid "\tGuard cells (x,y,z): " msgstr "" @@ -167,17 +172,17 @@ msgid "" "\tLine: {:s}" msgstr "" -#: ../src/bout++.cxx:563 +#: ../src/bout++.cxx:570 #, c++-format msgid "\tLAPACK support {}\n" msgstr "" -#: ../src/bout++.cxx:586 +#: ../src/bout++.cxx:591 #, c++-format msgid "\tMessage stack {}\n" msgstr "" -#: ../src/bout++.cxx:560 +#: ../src/bout++.cxx:567 #, c++-format msgid "\tMetrics mode is {}\n" msgstr "" @@ -187,98 +192,94 @@ msgstr "" msgid "\tMultiple '=' in command-line argument '{:s}'\n" msgstr "" -#: ../src/bout++.cxx:562 +#: ../src/bout++.cxx:569 #, c++-format msgid "\tNatural language support {}\n" msgstr "" -#: ../src/bout++.cxx:567 +#: ../src/bout++.cxx:574 #, c++-format msgid "\tNetCDF support {}{}\n" msgstr "" -#: ../src/bout++.cxx:577 +#: ../src/bout++.cxx:585 #, c++-format -msgid "\tOpenMP parallelisation {}" +msgid "\tOpenMP parallelisation {}, using {} threads\n" msgstr "" #. Mark the option as used #. Option not found -#: ../src/sys/options.cxx:311 ../src/sys/options.cxx:380 -#: ../src/sys/options.cxx:415 ../src/sys/options.cxx:457 -#: ../src/sys/options.cxx:717 ../src/sys/options.cxx:744 -#: ../src/sys/options.cxx:771 ../include/bout/options.hxx:516 -#: ../include/bout/options.hxx:549 ../include/bout/options.hxx:573 -#: ../include/bout/options.hxx:820 +#: ../include/bout/options.hxx:586 ../include/bout/options.hxx:619 +#: ../include/bout/options.hxx:643 ../include/bout/options.hxx:896 msgid "\tOption " msgstr "\t选项 " -#: ../src/sys/options.cxx:447 -#, c++-format -msgid "\tOption '{:s}': Boolean expected. Got '{:s}'\n" -msgstr "" +#: ../src/sys/options.cxx:369 +#, fuzzy, c++-format +msgid "\tOption {} = {}" +msgstr "\t选项 " #: ../src/sys/options/options_ini.cxx:70 #, c++-format msgid "\tOptions file '{:s}' not found\n" msgstr "" -#: ../src/bout++.cxx:568 +#: ../src/bout++.cxx:576 #, c++-format msgid "\tPETSc support {}\n" msgstr "" -#: ../src/bout++.cxx:571 +#: ../src/bout++.cxx:579 #, c++-format msgid "\tPVODE support {}\n" msgstr "" -#: ../src/bout++.cxx:557 +#: ../src/bout++.cxx:564 msgid "\tParallel NetCDF support disabled\n" msgstr "" -#: ../src/bout++.cxx:555 +#: ../src/bout++.cxx:562 msgid "\tParallel NetCDF support enabled\n" msgstr "" -#: ../src/bout++.cxx:569 +#: ../src/bout++.cxx:577 #, c++-format msgid "\tPretty function name support {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:437 +#: ../src/mesh/impls/bout/boutmesh.cxx:473 msgid "\tRead nz from input grid file\n" msgstr "" -#: ../src/mesh/mesh.cxx:238 +#: ../src/mesh/mesh.cxx:249 msgid "\tReading contravariant vector " msgstr "" -#: ../src/mesh/mesh.cxx:231 ../src/mesh/mesh.cxx:252 +#: ../src/mesh/mesh.cxx:242 ../src/mesh/mesh.cxx:263 msgid "\tReading covariant vector " msgstr "" -#: ../src/bout++.cxx:548 +#: ../src/bout++.cxx:555 #, c++-format msgid "\tRuntime error checking {}" msgstr "" -#: ../src/bout++.cxx:573 +#: ../src/bout++.cxx:581 #, c++-format msgid "\tSLEPc support {}\n" msgstr "" -#: ../src/bout++.cxx:574 +#: ../src/bout++.cxx:582 #, c++-format msgid "\tSUNDIALS support {}\n" msgstr "" -#: ../src/bout++.cxx:572 +#: ../src/bout++.cxx:580 #, c++-format msgid "\tScore-P support {}\n" msgstr "" -#: ../src/bout++.cxx:584 +#: ../src/bout++.cxx:589 #, fuzzy, c++-format msgid "\tSignal handling support {}\n" msgstr "\t测试关掉\n" @@ -288,7 +289,7 @@ msgstr "\t测试关掉\n" msgid "\tUsing a timestep {:e}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:577 +#: ../src/mesh/impls/bout/boutmesh.cxx:613 msgid "\tdone\n" msgstr "" @@ -298,7 +299,7 @@ msgid "" "\tSplit Runge-Kutta-Legendre and SSP-RK3 solver\n" msgstr "" -#: ../src/bout++.cxx:371 +#: ../src/bout++.cxx:378 msgid "" "\n" " -d \t\tLook in for input/output files\n" @@ -309,7 +310,7 @@ msgid "" " -q, --quiet\t\t\tDecrease verbosity\n" msgstr "" -#: ../src/sys/expressionparser.cxx:302 +#: ../src/sys/expressionparser.cxx:341 #, c++-format msgid "" "\n" @@ -317,7 +318,7 @@ msgid "" " Did you mean '{0}'?" msgstr "" -#: ../src/solver/solver.cxx:580 +#: ../src/solver/solver.cxx:586 #, fuzzy, c++-format msgid "" "\n" @@ -326,7 +327,7 @@ msgstr "" "\n" "计算结束于 {:s}\n" -#: ../src/solver/solver.cxx:532 +#: ../src/solver/solver.cxx:540 #, fuzzy, c++-format msgid "" "\n" @@ -338,7 +339,7 @@ msgstr "" #. Raw string to help with the formatting of the message, and a #. separate variable so clang-format doesn't barf on the #. exception -#: ../src/sys/options.cxx:1102 +#: ../src/sys/options.cxx:1158 msgid "" "\n" "There were unused input options:\n" @@ -366,7 +367,7 @@ msgid "" "{}" msgstr "" -#: ../src/bout++.cxx:382 +#: ../src/bout++.cxx:389 #, c++-format msgid "" " --print-config\t\tPrint the compile-time configuration\n" @@ -399,55 +400,55 @@ msgid "" "model source (e.g. {:s}.cxx)\n" msgstr "" -#: ../src/bout++.cxx:379 +#: ../src/bout++.cxx:386 msgid " -c, --color\t\t\tColor output using bout-log-color\n" msgstr "" -#: ../include/bout/options.hxx:823 +#: ../include/bout/options.hxx:899 msgid ") overwritten with:" msgstr "" -#: ../src/bout++.cxx:550 +#: ../src/bout++.cxx:557 #, c++-format msgid ", level {}" msgstr "" -#: ../src/bout++.cxx:579 -#, c++-format -msgid ", using {} threads" -msgstr "" - #: ../tests/unit/src/test_bout++.cxx:352 msgid "4 of 8" msgstr "" -#: ../src/sys/options.cxx:868 +#: ../src/sys/options.cxx:895 msgid "All options used\n" msgstr "" -#: ../src/bout++.cxx:528 +#: ../src/bout++.cxx:535 #, c++-format msgid "BOUT++ version {:s}\n" msgstr "" -#: ../src/bout++.cxx:143 +#: ../src/bout++.cxx:147 msgid "Bad command line arguments:\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:559 +#: ../src/sys/expressionparser.cxx:192 +#, c++-format +msgid "Boolean operator argument {:e} is not a bool" +msgstr "" + +#: ../src/mesh/impls/bout/boutmesh.cxx:595 msgid "Boundary regions in this processor: " msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:355 +#: ../src/mesh/impls/bout/boutmesh.cxx:348 #, c++-format msgid "Cannot split {:d} X points equally between {:d} processors\n" msgstr "" -#: ../src/bout++.cxx:818 +#: ../src/bout++.cxx:829 msgid "Check if a file exists, and exit if it does." msgstr "" -#: ../src/bout++.cxx:533 +#: ../src/bout++.cxx:540 #, fuzzy, c++-format msgid "" "Code compiled on {:s} at {:s}\n" @@ -460,7 +461,7 @@ msgstr "" msgid "Command line" msgstr "" -#: ../src/bout++.cxx:544 ../tests/unit/src/test_bout++.cxx:358 +#: ../src/bout++.cxx:551 ../tests/unit/src/test_bout++.cxx:358 msgid "Compile-time options:\n" msgstr "" @@ -468,16 +469,16 @@ msgstr "" msgid "Compiled with flags" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:568 +#: ../src/mesh/impls/bout/boutmesh.cxx:604 msgid "Constructing default regions" msgstr "" -#: ../src/bout++.cxx:520 +#: ../src/bout++.cxx:527 #, c++-format msgid "Could not create PID file {:s}" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:318 +#: ../src/mesh/impls/bout/boutmesh.cxx:309 msgid "" "Could not find a valid value for NXPE. Try a different number of processors." msgstr "" @@ -487,28 +488,28 @@ msgstr "" msgid "Could not open output file '{:s}'\n" msgstr "" -#: ../src/bout++.cxx:652 +#: ../src/bout++.cxx:657 #, c++-format msgid "Could not open {:s}/{:s}.{:d} for writing" msgstr "" #. Error reading -#: ../src/mesh/mesh.cxx:532 +#: ../src/mesh/mesh.cxx:543 #, c++-format msgid "Could not read integer array '{:s}'\n" msgstr "" #. Failed . Probably not important enough to stop the simulation -#: ../src/bout++.cxx:632 +#: ../src/bout++.cxx:637 msgid "Could not run bout-log-color. Make sure it is in your PATH\n" msgstr "" -#: ../src/solver/solver.cxx:765 +#: ../src/solver/solver.cxx:772 #, c++-format msgid "Couldn't add Monitor: {:g} is not a multiple of {:g}!" msgstr "" -#: ../src/sys/expressionparser.cxx:273 +#: ../src/sys/expressionparser.cxx:312 #, c++-format msgid "" "Couldn't find generator '{}'. BOUT++ expressions are now case-sensitive, so " @@ -517,69 +518,69 @@ msgid "" "{}" msgstr "" -#: ../src/mesh/mesh.cxx:568 +#: ../src/mesh/mesh.cxx:587 #, c++-format msgid "Couldn't find region {:s} in regionMap2D" msgstr "" -#: ../src/mesh/mesh.cxx:560 +#: ../src/mesh/mesh.cxx:571 ../src/mesh/mesh.cxx:579 #, c++-format msgid "Couldn't find region {:s} in regionMap3D" msgstr "" -#: ../src/mesh/mesh.cxx:576 +#: ../src/mesh/mesh.cxx:595 #, c++-format msgid "Couldn't find region {:s} in regionMapPerp" msgstr "" #. Convert any exceptions to something a bit more useful -#: ../src/sys/options.cxx:336 +#: ../src/sys/options.cxx:361 #, c++-format msgid "Couldn't get {} from option {:s} = '{:s}': {}" msgstr "" -#: ../src/bout++.cxx:508 +#: ../src/bout++.cxx:515 #, fuzzy, c++-format msgid "DataDir \"{:s}\" does not exist or is not accessible\n" msgstr "\"{:s}\" 不存在或不可访问\n" -#: ../src/bout++.cxx:505 +#: ../src/bout++.cxx:512 #, fuzzy, c++-format msgid "DataDir \"{:s}\" is not a directory\n" msgstr "\"{:s}\" 不是目录\n" -#: ../src/solver/solver.cxx:665 +#: ../src/solver/solver.cxx:671 msgid "ERROR: Solver is already initialised\n" msgstr "" -#: ../src/bout++.cxx:209 +#: ../src/bout++.cxx:216 #, fuzzy, c++-format msgid "Error encountered during initialisation: {:s}\n" msgstr "启动时遇到错误 : {:s}\n" -#: ../src/bout++.cxx:744 +#: ../src/bout++.cxx:751 msgid "Error whilst writing settings" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:332 +#: ../src/mesh/impls/bout/boutmesh.cxx:323 #, c++-format msgid "Error: nx must be greater than 2 times MXG (2 * {:d})" msgstr "" -#: ../src/solver/solver.cxx:512 +#: ../src/solver/solver.cxx:520 msgid "Failed to initialise solver-> Aborting\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:290 +#: ../src/mesh/impls/bout/boutmesh.cxx:281 #, c++-format msgid "Finding value for NXPE (ideal = {:f})\n" msgstr "" -#: ../src/solver/solver.cxx:668 +#: ../src/solver/solver.cxx:674 msgid "Initialising solver\n" msgstr "" -#: ../src/bout++.cxx:494 +#: ../src/bout++.cxx:501 msgid "" "Input and output file for settings must be different.\n" "Provide -o to avoid this issue.\n" @@ -589,122 +590,122 @@ msgstr "" msgid "Invalid command line option '-' found - maybe check whitespace?" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:400 +#: ../src/mesh/impls/bout/boutmesh.cxx:436 msgid "Loading mesh" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:415 +#: ../src/mesh/impls/bout/boutmesh.cxx:451 msgid "Mesh must contain nx" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:419 +#: ../src/mesh/impls/bout/boutmesh.cxx:455 msgid "Mesh must contain ny" msgstr "" #. Not found -#: ../src/mesh/mesh.cxx:536 +#: ../src/mesh/mesh.cxx:547 #, c++-format msgid "Missing integer array {:s}\n" msgstr "" -#: ../src/solver/solver.cxx:905 +#: ../src/solver/solver.cxx:911 #, c++-format msgid "Monitor signalled to quit (exception {})\n" msgstr "" -#: ../src/solver/solver.cxx:883 +#: ../src/solver/solver.cxx:889 #, c++-format msgid "Monitor signalled to quit (return code {})" msgstr "" -#: ../src/bout++.cxx:823 +#: ../src/bout++.cxx:834 msgid "Name of file whose existence triggers a stop" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:565 +#: ../src/mesh/impls/bout/boutmesh.cxx:601 msgid "No boundary regions in this processor" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:550 +#: ../src/mesh/impls/bout/boutmesh.cxx:586 msgid "No boundary regions; domain is periodic\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:254 +#: ../src/mesh/impls/bout/boutmesh.cxx:245 #, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in x direction ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:267 +#: ../src/mesh/impls/bout/boutmesh.cxx:258 #, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in y direction ({:d})\n" msgstr "" #. Less than 2 time-steps left -#: ../src/bout++.cxx:896 +#: ../src/bout++.cxx:908 #, c++-format msgid "Only {:e} seconds ({:.2f} steps) left. Quitting\n" msgstr "" -#: ../src/sys/options.cxx:303 ../src/sys/options.cxx:345 -#: ../src/sys/options.cxx:393 ../src/sys/options.cxx:428 -#: ../src/sys/options.cxx:703 ../src/sys/options.cxx:730 -#: ../src/sys/options.cxx:757 +#: ../src/sys/options.cxx:382 ../src/sys/options.cxx:398 +#: ../src/sys/options.cxx:441 ../src/sys/options.cxx:471 +#: ../src/sys/options.cxx:745 ../src/sys/options.cxx:767 +#: ../src/sys/options.cxx:789 #, c++-format msgid "Option {:s} has no value" msgstr "" #. Doesn't exist -#: ../src/sys/options.cxx:159 +#: ../src/sys/options.cxx:172 #, c++-format msgid "Option {:s}:{:s} does not exist" msgstr "" -#: ../include/bout/options.hxx:828 +#: ../include/bout/options.hxx:904 #, c++-format msgid "" "Options: Setting a value from same source ({:s}) to new value '{:s}' - old " "value was '{:s}'." msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:552 +#: ../src/mesh/impls/bout/boutmesh.cxx:588 msgid "Possible boundary regions are: " msgstr "" -#: ../src/bout++.cxx:538 +#: ../src/bout++.cxx:545 #, c++-format msgid "" "Processor number: {:d} of {:d}\n" "\n" msgstr "" -#: ../src/mesh/mesh.cxx:609 +#: ../src/mesh/mesh.cxx:642 #, c++-format msgid "Registered region 2D {:s}" msgstr "" -#: ../src/mesh/mesh.cxx:599 +#: ../src/mesh/mesh.cxx:632 #, c++-format msgid "Registered region 3D {:s}" msgstr "" -#: ../src/mesh/mesh.cxx:619 +#: ../src/mesh/mesh.cxx:652 #, c++-format msgid "Registered region Perp {:s}" msgstr "" -#: ../src/bout++.cxx:529 +#: ../src/bout++.cxx:536 #, c++-format msgid "Revision: {:s}\n" msgstr "" -#: ../src/solver/solver.cxx:581 +#: ../src/solver/solver.cxx:587 msgid "Run time : " msgstr "计算时间" #. / Run the solver -#: ../src/solver/solver.cxx:525 +#: ../src/solver/solver.cxx:533 msgid "" "Running simulation\n" "\n" @@ -716,64 +717,64 @@ msgstr "" msgid "Signal" msgstr "" -#: ../src/bout++.cxx:865 +#: ../src/bout++.cxx:876 msgid "" "Sim Time | RHS evals | Wall Time | Calc Inv Comm I/O SOLVER\n" "\n" msgstr "" -#: ../src/bout++.cxx:868 +#: ../src/bout++.cxx:879 msgid "" "Sim Time | RHS_e evals | RHS_I evals | Wall Time | Calc Inv " "Comm I/O SOLVER\n" "\n" msgstr "" -#: ../src/solver/solver.cxx:506 +#: ../src/solver/solver.cxx:514 #, c++-format msgid "Solver running for {:d} outputs with monitor timestep of {:e}\n" msgstr "" -#: ../src/solver/solver.cxx:502 +#: ../src/solver/solver.cxx:510 #, c++-format msgid "Solver running for {:d} outputs with output timestep of {:e}\n" msgstr "" -#: ../src/solver/solver.cxx:781 +#: ../src/solver/solver.cxx:788 #, c++-format msgid "" "Solver::addMonitor: Cannot reduce timestep (from {:g} to {:g}) after init is " "called!" msgstr "" -#: ../src/solver/solver.cxx:1281 +#: ../src/solver/solver.cxx:1289 #, c++-format msgid "" "Time derivative at wrong location - Field is at {:s}, derivative is at {:s} " "for field '{:s}'\n" msgstr "" -#: ../src/solver/solver.cxx:1480 +#: ../src/solver/solver.cxx:1494 #, c++-format msgid "Time derivative for variable '{:s}' not set" msgstr "" -#: ../src/mesh/mesh.cxx:605 +#: ../src/mesh/mesh.cxx:638 #, c++-format msgid "Trying to add an already existing region {:s} to regionMap2D" msgstr "" -#: ../src/mesh/mesh.cxx:595 +#: ../src/mesh/mesh.cxx:614 #, c++-format msgid "Trying to add an already existing region {:s} to regionMap3D" msgstr "" -#: ../src/mesh/mesh.cxx:616 +#: ../src/mesh/mesh.cxx:649 #, c++-format msgid "Trying to add an already existing region {:s} to regionMapPerp" msgstr "" -#: ../src/sys/options.cxx:99 ../src/sys/options.cxx:138 +#: ../src/sys/options.cxx:112 ../src/sys/options.cxx:151 #, c++-format msgid "" "Trying to index Option '{0}' with '{1}', but '{0}' is a value, not a " @@ -782,37 +783,37 @@ msgid "" "rename one of them.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:1462 +#: ../src/mesh/coordinates.cxx:1464 msgid "" "Unrecognised paralleltransform option.\n" "Valid choices are 'identity', 'shifted', 'fci'" msgstr "" -#: ../src/sys/options.cxx:872 +#: ../src/sys/options.cxx:899 msgid "Unused options:\n" msgstr "" -#: ../src/bout++.cxx:439 +#: ../src/bout++.cxx:446 #, c++-format msgid "Usage is {:s} -d \n" msgstr "" -#: ../src/bout++.cxx:448 +#: ../src/bout++.cxx:455 #, c++-format msgid "Usage is {:s} -f \n" msgstr "" -#: ../src/bout++.cxx:466 +#: ../src/bout++.cxx:473 #, c++-format msgid "Usage is {:s} -l \n" msgstr "" -#: ../src/bout++.cxx:457 +#: ../src/bout++.cxx:464 #, c++-format msgid "Usage is {:s} -o \n" msgstr "" -#: ../src/bout++.cxx:353 +#: ../src/bout++.cxx:360 #, c++-format msgid "Usage is {} {} \n" msgstr "" @@ -823,7 +824,7 @@ msgstr "" #. Print help message -- note this will be displayed once per processor as we've not #. started MPI yet. -#: ../src/bout++.cxx:367 +#: ../src/bout++.cxx:374 #, c++-format msgid "" "Usage: {:s} [-d ] [-f ] [restart [append]] " @@ -831,94 +832,99 @@ msgid "" msgstr "" #. restart file should be written by physics model -#: ../src/solver/solver.cxx:921 +#: ../src/solver/solver.cxx:927 msgid "User signalled to quit. Returning\n" msgstr "" -#: ../src/sys/options.cxx:373 +#: ../src/sys/options.cxx:486 +#, fuzzy, c++-format +msgid "Value for option {:s} = {:e} is not a bool" +msgstr "\"{:s}\" 不是目录\n" + +#: ../src/sys/options.cxx:426 #, c++-format msgid "Value for option {:s} = {:e} is not an integer" msgstr "" -#: ../src/sys/options.cxx:408 +#: ../src/sys/options.cxx:456 #, c++-format msgid "Value for option {:s} cannot be converted to a BoutReal" msgstr "" -#: ../src/sys/options.cxx:581 +#: ../src/sys/options.cxx:623 #, c++-format msgid "Value for option {:s} cannot be converted to a Field2D" msgstr "" -#: ../src/sys/options.cxx:529 +#: ../src/sys/options.cxx:571 #, c++-format msgid "Value for option {:s} cannot be converted to a Field3D" msgstr "" -#: ../src/sys/options.cxx:663 +#: ../src/sys/options.cxx:705 #, c++-format msgid "Value for option {:s} cannot be converted to a FieldPerp" msgstr "" -#: ../src/sys/options.cxx:451 +#: ../src/sys/options.cxx:491 #, c++-format msgid "Value for option {:s} cannot be converted to a bool" msgstr "" -#: ../src/sys/options.cxx:709 +#: ../src/sys/options.cxx:751 #, c++-format msgid "Value for option {:s} cannot be converted to an Array" msgstr "" -#: ../src/sys/options.cxx:736 +#: ../src/sys/options.cxx:773 #, c++-format msgid "Value for option {:s} cannot be converted to an Matrix" msgstr "" -#: ../src/sys/options.cxx:763 +#: ../src/sys/options.cxx:795 #, c++-format msgid "Value for option {:s} cannot be converted to an Tensor" msgstr "" #. Another type which can't be converted -#: ../src/sys/options.cxx:365 +#: ../src/sys/options.cxx:418 #, c++-format msgid "Value for option {:s} is not an integer" msgstr "" -#: ../src/solver/solver.cxx:1232 ../src/solver/solver.cxx:1238 +#: ../src/solver/solver.cxx:1240 ../src/solver/solver.cxx:1246 #, c++-format msgid "Variable '{:s}' not initialised" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:431 +#: ../src/mesh/impls/bout/boutmesh.cxx:467 #, c++-format msgid "" "WARNING: Number of toroidal points should be 2^n for efficient FFT " "performance -- consider changing MZ ({:d}) if using FFTs\n" msgstr "" -#: ../src/mesh/coordinates.cxx:633 +#: ../src/mesh/coordinates.cxx:635 msgid "WARNING: extrapolating input mesh quantities into x-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:410 +#: ../src/mesh/coordinates.cxx:412 msgid "" "WARNING: extrapolating input mesh quantities into x-boundary cells. Set " "option extrapolate_x=false to disable this.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:638 +#: ../src/mesh/coordinates.cxx:640 msgid "WARNING: extrapolating input mesh quantities into y-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:415 +#: ../src/mesh/coordinates.cxx:417 msgid "" "WARNING: extrapolating input mesh quantities into y-boundary cells. Set " "option extrapolate_y=false to disable this.\n" msgstr "" -#: ../src/bout++.cxx:814 +#: ../src/bout++.cxx:825 msgid "Wall time limit in hours. By default (< 0), no limit" msgstr "" @@ -928,7 +934,7 @@ msgid "Writing options to file {:s}\n" msgstr "" #. / The source label given to default values -#: ../src/sys/options.cxx:15 +#: ../src/sys/options.cxx:34 msgid "default" msgstr "" @@ -939,9 +945,5 @@ msgstr "" #~ msgid "\tChecking enabled, level {:d}\n" #~ msgstr "\t测试打开,级别 {:d}\n" -#, fuzzy -#~ msgid "Option {:s} is not a section" -#~ msgstr "\"{:s}\" 不是目录\n" - #~ msgid "Error encountered during initialisation\n" #~ msgstr "启动时遇到错误\n" diff --git a/locale/zh_TW/libbout.po b/locale/zh_TW/libbout.po index de0230d68d..abf44db51f 100644 --- a/locale/zh_TW/libbout.po +++ b/locale/zh_TW/libbout.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: BOUT++ 4.2.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-09-12 09:17+0100\n" +"POT-Creation-Date: 2025-08-13 23:37+0100\n" "PO-Revision-Date: 2018-10-22 22:56+0100\n" "Last-Translator: \n" "Language-Team: Chinese (traditional)\n" @@ -16,64 +16,69 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:191 +#: ../src/mesh/impls/bout/boutmesh.cxx:182 #, c++-format msgid "" "\t -> Core region jyseps2_1-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:224 +#: ../src/mesh/impls/bout/boutmesh.cxx:215 #, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_1 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:199 +#: ../src/mesh/impls/bout/boutmesh.cxx:190 #, c++-format msgid "" "\t -> Core region jyseps2_2-jyseps1_2 ({:d}-{:d} = {:d}) must be a multiple " "of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:309 +#: ../src/mesh/impls/bout/boutmesh.cxx:300 msgid "\t -> Good value\n" msgstr "\t -> 好的號碼\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:180 +#: ../src/mesh/impls/bout/boutmesh.cxx:171 #, c++-format msgid "" "\t -> Leg region jyseps1_1+1 ({:d}) must be a multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:215 +#: ../src/mesh/impls/bout/boutmesh.cxx:206 #, c++-format msgid "" "\t -> leg region jyseps1_2-ny_inner+1 ({:d}-{:d}+1 = {:d}) must be a " "multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:232 +#: ../src/mesh/impls/bout/boutmesh.cxx:223 #, c++-format msgid "" "\t -> leg region ny-jyseps2_2-1 ({:d}-{:d}-1 = {:d}) must be a multiple of " "MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:208 +#: ../src/mesh/impls/bout/boutmesh.cxx:199 #, c++-format msgid "" "\t -> leg region ny_inner-jyseps2_1-1 ({:d}-{:d}-1 = {:d}) must be a " "multiple of MYSUB ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:175 +#: ../src/mesh/impls/bout/boutmesh.cxx:166 #, c++-format msgid "\t -> ny/NYPE ({:d}/{:d} = {:d}) must be >= MYG ({:d})\n" msgstr "" #: ../src/bout++.cxx:575 +#, fuzzy, c++-format +msgid "\tADIOS2 support {}\n" +msgstr "\tOpenMP並行化已禁用\n" + +#: ../src/bout++.cxx:583 #, c++-format msgid "\tBacktrace in exceptions {}\n" msgstr "" @@ -82,40 +87,40 @@ msgstr "" #. Processors divide equally #. Mesh in X divides equally #. Mesh in Y divides equally -#: ../src/mesh/impls/bout/boutmesh.cxx:297 +#: ../src/mesh/impls/bout/boutmesh.cxx:288 #, fuzzy, c++-format msgid "\tCandidate value: {:d}\n" msgstr "\t候選人數目 {:d}\n" -#: ../src/bout++.cxx:576 +#: ../src/bout++.cxx:584 #, c++-format msgid "\tColour in logs {}\n" msgstr "" -#: ../src/bout++.cxx:594 +#: ../src/bout++.cxx:599 msgid "\tCommand line options for this run : " msgstr "" #. The stringify is needed here as BOUT_FLAGS_STRING may already contain quoted strings #. which could cause problems (e.g. terminate strings). -#: ../src/bout++.cxx:590 +#: ../src/bout++.cxx:595 #, fuzzy, c++-format msgid "\tCompiled with flags : {:s}\n" msgstr "\t用設置編譯: {:s}\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:324 +#: ../src/mesh/impls/bout/boutmesh.cxx:315 #, fuzzy, c++-format msgid "" "\tDomain split (NXPE={:d}, NYPE={:d}) into domains (localNx={:d}, " "localNy={:d})\n" msgstr "\t域 (NXPE={:d}, NYPE={:d}) 分裂成域 (localNx={:d}, localNy={:d})\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:364 +#: ../src/mesh/impls/bout/boutmesh.cxx:357 #, c++-format msgid "\tERROR: Cannot split {:d} Y points equally between {:d} processors\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:372 +#: ../src/mesh/impls/bout/boutmesh.cxx:365 #, c++-format msgid "\tERROR: Cannot split {:d} Z points equally between {:d} processors\n" msgstr "" @@ -132,31 +137,31 @@ msgstr "" msgid "\tEmpty key or value in command line '{:s}'\n" msgstr "\t命令行中的空鍵或值 '{:s}'\n" -#: ../src/bout++.cxx:582 +#: ../src/bout++.cxx:587 #, c++-format msgid "\tExtra debug output {}\n" msgstr "" -#: ../src/bout++.cxx:561 +#: ../src/bout++.cxx:568 #, c++-format msgid "\tFFT support {}\n" msgstr "" -#: ../src/bout++.cxx:585 +#: ../src/bout++.cxx:590 #, c++-format msgid "\tField name tracking {}\n" msgstr "" -#: ../src/bout++.cxx:583 +#: ../src/bout++.cxx:588 #, c++-format msgid "\tFloating-point exceptions {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:440 +#: ../src/mesh/impls/bout/boutmesh.cxx:476 msgid "\tGrid size: " msgstr "\t網格大小: " -#: ../src/mesh/impls/bout/boutmesh.cxx:463 +#: ../src/mesh/impls/bout/boutmesh.cxx:499 msgid "\tGuard cells (x,y,z): " msgstr "" @@ -167,17 +172,17 @@ msgid "" "\tLine: {:s}" msgstr "" -#: ../src/bout++.cxx:563 +#: ../src/bout++.cxx:570 #, c++-format msgid "\tLAPACK support {}\n" msgstr "" -#: ../src/bout++.cxx:586 +#: ../src/bout++.cxx:591 #, c++-format msgid "\tMessage stack {}\n" msgstr "" -#: ../src/bout++.cxx:560 +#: ../src/bout++.cxx:567 #, c++-format msgid "\tMetrics mode is {}\n" msgstr "" @@ -187,99 +192,95 @@ msgstr "" msgid "\tMultiple '=' in command-line argument '{:s}'\n" msgstr "" -#: ../src/bout++.cxx:562 +#: ../src/bout++.cxx:569 #, c++-format msgid "\tNatural language support {}\n" msgstr "" -#: ../src/bout++.cxx:567 +#: ../src/bout++.cxx:574 #, fuzzy, c++-format msgid "\tNetCDF support {}{}\n" msgstr "\tOpenMP並行化已禁用\n" -#: ../src/bout++.cxx:577 +#: ../src/bout++.cxx:585 #, fuzzy, c++-format -msgid "\tOpenMP parallelisation {}" -msgstr "\tOpenMP並行化已禁用\n" +msgid "\tOpenMP parallelisation {}, using {} threads\n" +msgstr "\t啟用OpenMP並行化。 使用{:d}個線程\n" #. Mark the option as used #. Option not found -#: ../src/sys/options.cxx:311 ../src/sys/options.cxx:380 -#: ../src/sys/options.cxx:415 ../src/sys/options.cxx:457 -#: ../src/sys/options.cxx:717 ../src/sys/options.cxx:744 -#: ../src/sys/options.cxx:771 ../include/bout/options.hxx:516 -#: ../include/bout/options.hxx:549 ../include/bout/options.hxx:573 -#: ../include/bout/options.hxx:820 +#: ../include/bout/options.hxx:586 ../include/bout/options.hxx:619 +#: ../include/bout/options.hxx:643 ../include/bout/options.hxx:896 msgid "\tOption " msgstr "\t選項 " -#: ../src/sys/options.cxx:447 +#: ../src/sys/options.cxx:369 #, fuzzy, c++-format -msgid "\tOption '{:s}': Boolean expected. Got '{:s}'\n" -msgstr "\t選項 '{:s}': 布爾預期. 拿到 '{:s}'\n" +msgid "\tOption {} = {}" +msgstr "\t選項 " #: ../src/sys/options/options_ini.cxx:70 #, fuzzy, c++-format msgid "\tOptions file '{:s}' not found\n" msgstr "\t找不到選項文件 '{:s}'\n" -#: ../src/bout++.cxx:568 +#: ../src/bout++.cxx:576 #, c++-format msgid "\tPETSc support {}\n" msgstr "" -#: ../src/bout++.cxx:571 +#: ../src/bout++.cxx:579 #, c++-format msgid "\tPVODE support {}\n" msgstr "" -#: ../src/bout++.cxx:557 +#: ../src/bout++.cxx:564 #, fuzzy msgid "\tParallel NetCDF support disabled\n" msgstr "\tOpenMP並行化已禁用\n" -#: ../src/bout++.cxx:555 +#: ../src/bout++.cxx:562 msgid "\tParallel NetCDF support enabled\n" msgstr "" -#: ../src/bout++.cxx:569 +#: ../src/bout++.cxx:577 #, c++-format msgid "\tPretty function name support {}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:437 +#: ../src/mesh/impls/bout/boutmesh.cxx:473 msgid "\tRead nz from input grid file\n" msgstr "" -#: ../src/mesh/mesh.cxx:238 +#: ../src/mesh/mesh.cxx:249 msgid "\tReading contravariant vector " msgstr "" -#: ../src/mesh/mesh.cxx:231 ../src/mesh/mesh.cxx:252 +#: ../src/mesh/mesh.cxx:242 ../src/mesh/mesh.cxx:263 msgid "\tReading covariant vector " msgstr "" -#: ../src/bout++.cxx:548 +#: ../src/bout++.cxx:555 #, c++-format msgid "\tRuntime error checking {}" msgstr "" -#: ../src/bout++.cxx:573 +#: ../src/bout++.cxx:581 #, c++-format msgid "\tSLEPc support {}\n" msgstr "" -#: ../src/bout++.cxx:574 +#: ../src/bout++.cxx:582 #, c++-format msgid "\tSUNDIALS support {}\n" msgstr "" -#: ../src/bout++.cxx:572 +#: ../src/bout++.cxx:580 #, c++-format msgid "\tScore-P support {}\n" msgstr "" -#: ../src/bout++.cxx:584 +#: ../src/bout++.cxx:589 #, fuzzy, c++-format msgid "\tSignal handling support {}\n" msgstr "\t測試關掉\n" @@ -289,7 +290,7 @@ msgstr "\t測試關掉\n" msgid "\tUsing a timestep {:e}\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:577 +#: ../src/mesh/impls/bout/boutmesh.cxx:613 msgid "\tdone\n" msgstr "\t完\n" @@ -299,7 +300,7 @@ msgid "" "\tSplit Runge-Kutta-Legendre and SSP-RK3 solver\n" msgstr "" -#: ../src/bout++.cxx:371 +#: ../src/bout++.cxx:378 msgid "" "\n" " -d \t\tLook in for input/output files\n" @@ -310,7 +311,7 @@ msgid "" " -q, --quiet\t\t\tDecrease verbosity\n" msgstr "" -#: ../src/sys/expressionparser.cxx:302 +#: ../src/sys/expressionparser.cxx:341 #, c++-format msgid "" "\n" @@ -318,7 +319,7 @@ msgid "" " Did you mean '{0}'?" msgstr "" -#: ../src/solver/solver.cxx:580 +#: ../src/solver/solver.cxx:586 #, fuzzy, c++-format msgid "" "\n" @@ -327,7 +328,7 @@ msgstr "" "\n" "计算结束于 {:s}\n" -#: ../src/solver/solver.cxx:532 +#: ../src/solver/solver.cxx:540 #, fuzzy, c++-format msgid "" "\n" @@ -339,7 +340,7 @@ msgstr "" #. Raw string to help with the formatting of the message, and a #. separate variable so clang-format doesn't barf on the #. exception -#: ../src/sys/options.cxx:1102 +#: ../src/sys/options.cxx:1158 msgid "" "\n" "There were unused input options:\n" @@ -367,7 +368,7 @@ msgid "" "{}" msgstr "" -#: ../src/bout++.cxx:382 +#: ../src/bout++.cxx:389 #, c++-format msgid "" " --print-config\t\tPrint the compile-time configuration\n" @@ -400,55 +401,55 @@ msgid "" "model source (e.g. {:s}.cxx)\n" msgstr "" -#: ../src/bout++.cxx:379 +#: ../src/bout++.cxx:386 msgid " -c, --color\t\t\tColor output using bout-log-color\n" msgstr "" -#: ../include/bout/options.hxx:823 +#: ../include/bout/options.hxx:899 msgid ") overwritten with:" msgstr "" -#: ../src/bout++.cxx:550 +#: ../src/bout++.cxx:557 #, c++-format msgid ", level {}" msgstr "" -#: ../src/bout++.cxx:579 -#, c++-format -msgid ", using {} threads" -msgstr "" - #: ../tests/unit/src/test_bout++.cxx:352 msgid "4 of 8" msgstr "" -#: ../src/sys/options.cxx:868 +#: ../src/sys/options.cxx:895 msgid "All options used\n" msgstr "" -#: ../src/bout++.cxx:528 +#: ../src/bout++.cxx:535 #, fuzzy, c++-format msgid "BOUT++ version {:s}\n" msgstr "BOUT++ 版 {:s}\n" -#: ../src/bout++.cxx:143 +#: ../src/bout++.cxx:147 msgid "Bad command line arguments:\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:559 +#: ../src/sys/expressionparser.cxx:192 +#, c++-format +msgid "Boolean operator argument {:e} is not a bool" +msgstr "" + +#: ../src/mesh/impls/bout/boutmesh.cxx:595 msgid "Boundary regions in this processor: " msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:355 +#: ../src/mesh/impls/bout/boutmesh.cxx:348 #, c++-format msgid "Cannot split {:d} X points equally between {:d} processors\n" msgstr "" -#: ../src/bout++.cxx:818 +#: ../src/bout++.cxx:829 msgid "Check if a file exists, and exit if it does." msgstr "" -#: ../src/bout++.cxx:533 +#: ../src/bout++.cxx:540 #, fuzzy, c++-format msgid "" "Code compiled on {:s} at {:s}\n" @@ -461,7 +462,7 @@ msgstr "" msgid "Command line" msgstr "" -#: ../src/bout++.cxx:544 ../tests/unit/src/test_bout++.cxx:358 +#: ../src/bout++.cxx:551 ../tests/unit/src/test_bout++.cxx:358 msgid "Compile-time options:\n" msgstr "編譯選項:\n" @@ -470,16 +471,16 @@ msgstr "編譯選項:\n" msgid "Compiled with flags" msgstr "\t用設置編譯: {:s}\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:568 +#: ../src/mesh/impls/bout/boutmesh.cxx:604 msgid "Constructing default regions" msgstr "" -#: ../src/bout++.cxx:520 +#: ../src/bout++.cxx:527 #, fuzzy, c++-format msgid "Could not create PID file {:s}" msgstr "無法打開輸出文件 '{:s}'\n" -#: ../src/mesh/impls/bout/boutmesh.cxx:318 +#: ../src/mesh/impls/bout/boutmesh.cxx:309 msgid "" "Could not find a valid value for NXPE. Try a different number of processors." msgstr "無法找到NXPE的有效值。 嘗試不同數量的處理器。" @@ -489,28 +490,28 @@ msgstr "無法找到NXPE的有效值。 嘗試不同數量的處理器。" msgid "Could not open output file '{:s}'\n" msgstr "無法打開輸出文件 '{:s}'\n" -#: ../src/bout++.cxx:652 +#: ../src/bout++.cxx:657 #, c++-format msgid "Could not open {:s}/{:s}.{:d} for writing" msgstr "" #. Error reading -#: ../src/mesh/mesh.cxx:532 +#: ../src/mesh/mesh.cxx:543 #, c++-format msgid "Could not read integer array '{:s}'\n" msgstr "" #. Failed . Probably not important enough to stop the simulation -#: ../src/bout++.cxx:632 +#: ../src/bout++.cxx:637 msgid "Could not run bout-log-color. Make sure it is in your PATH\n" msgstr "" -#: ../src/solver/solver.cxx:765 +#: ../src/solver/solver.cxx:772 #, c++-format msgid "Couldn't add Monitor: {:g} is not a multiple of {:g}!" msgstr "" -#: ../src/sys/expressionparser.cxx:273 +#: ../src/sys/expressionparser.cxx:312 #, c++-format msgid "" "Couldn't find generator '{}'. BOUT++ expressions are now case-sensitive, so " @@ -519,69 +520,69 @@ msgid "" "{}" msgstr "" -#: ../src/mesh/mesh.cxx:568 +#: ../src/mesh/mesh.cxx:587 #, c++-format msgid "Couldn't find region {:s} in regionMap2D" msgstr "" -#: ../src/mesh/mesh.cxx:560 +#: ../src/mesh/mesh.cxx:571 ../src/mesh/mesh.cxx:579 #, c++-format msgid "Couldn't find region {:s} in regionMap3D" msgstr "" -#: ../src/mesh/mesh.cxx:576 +#: ../src/mesh/mesh.cxx:595 #, c++-format msgid "Couldn't find region {:s} in regionMapPerp" msgstr "" #. Convert any exceptions to something a bit more useful -#: ../src/sys/options.cxx:336 +#: ../src/sys/options.cxx:361 #, c++-format msgid "Couldn't get {} from option {:s} = '{:s}': {}" msgstr "" -#: ../src/bout++.cxx:508 +#: ../src/bout++.cxx:515 #, fuzzy, c++-format msgid "DataDir \"{:s}\" does not exist or is not accessible\n" msgstr "\"{:s}\" 不存在或不可訪問\n" -#: ../src/bout++.cxx:505 +#: ../src/bout++.cxx:512 #, fuzzy, c++-format msgid "DataDir \"{:s}\" is not a directory\n" msgstr "\"{:s}\" 不是目錄\n" -#: ../src/solver/solver.cxx:665 +#: ../src/solver/solver.cxx:671 msgid "ERROR: Solver is already initialised\n" msgstr "" -#: ../src/bout++.cxx:209 +#: ../src/bout++.cxx:216 #, fuzzy, c++-format msgid "Error encountered during initialisation: {:s}\n" msgstr "啟動時遇到錯誤 : {:s}\n" -#: ../src/bout++.cxx:744 +#: ../src/bout++.cxx:751 msgid "Error whilst writing settings" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:332 +#: ../src/mesh/impls/bout/boutmesh.cxx:323 #, c++-format msgid "Error: nx must be greater than 2 times MXG (2 * {:d})" msgstr "" -#: ../src/solver/solver.cxx:512 +#: ../src/solver/solver.cxx:520 msgid "Failed to initialise solver-> Aborting\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:290 +#: ../src/mesh/impls/bout/boutmesh.cxx:281 #, c++-format msgid "Finding value for NXPE (ideal = {:f})\n" msgstr "" -#: ../src/solver/solver.cxx:668 +#: ../src/solver/solver.cxx:674 msgid "Initialising solver\n" msgstr "初始化求解器\n" -#: ../src/bout++.cxx:494 +#: ../src/bout++.cxx:501 msgid "" "Input and output file for settings must be different.\n" "Provide -o to avoid this issue.\n" @@ -591,122 +592,122 @@ msgstr "" msgid "Invalid command line option '-' found - maybe check whitespace?" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:400 +#: ../src/mesh/impls/bout/boutmesh.cxx:436 msgid "Loading mesh" msgstr "加載網格" -#: ../src/mesh/impls/bout/boutmesh.cxx:415 +#: ../src/mesh/impls/bout/boutmesh.cxx:451 msgid "Mesh must contain nx" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:419 +#: ../src/mesh/impls/bout/boutmesh.cxx:455 msgid "Mesh must contain ny" msgstr "" #. Not found -#: ../src/mesh/mesh.cxx:536 +#: ../src/mesh/mesh.cxx:547 #, c++-format msgid "Missing integer array {:s}\n" msgstr "" -#: ../src/solver/solver.cxx:905 +#: ../src/solver/solver.cxx:911 #, c++-format msgid "Monitor signalled to quit (exception {})\n" msgstr "" -#: ../src/solver/solver.cxx:883 +#: ../src/solver/solver.cxx:889 #, c++-format msgid "Monitor signalled to quit (return code {})" msgstr "" -#: ../src/bout++.cxx:823 +#: ../src/bout++.cxx:834 msgid "Name of file whose existence triggers a stop" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:565 +#: ../src/mesh/impls/bout/boutmesh.cxx:601 msgid "No boundary regions in this processor" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:550 +#: ../src/mesh/impls/bout/boutmesh.cxx:586 msgid "No boundary regions; domain is periodic\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:254 +#: ../src/mesh/impls/bout/boutmesh.cxx:245 #, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in x direction ({:d})\n" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:267 +#: ../src/mesh/impls/bout/boutmesh.cxx:258 #, c++-format msgid "" "Number of processors ({:d}) not divisible by NPs in y direction ({:d})\n" msgstr "" #. Less than 2 time-steps left -#: ../src/bout++.cxx:896 +#: ../src/bout++.cxx:908 #, c++-format msgid "Only {:e} seconds ({:.2f} steps) left. Quitting\n" msgstr "" -#: ../src/sys/options.cxx:303 ../src/sys/options.cxx:345 -#: ../src/sys/options.cxx:393 ../src/sys/options.cxx:428 -#: ../src/sys/options.cxx:703 ../src/sys/options.cxx:730 -#: ../src/sys/options.cxx:757 +#: ../src/sys/options.cxx:382 ../src/sys/options.cxx:398 +#: ../src/sys/options.cxx:441 ../src/sys/options.cxx:471 +#: ../src/sys/options.cxx:745 ../src/sys/options.cxx:767 +#: ../src/sys/options.cxx:789 #, fuzzy, c++-format msgid "Option {:s} has no value" msgstr "\"{:s}\" 不是目錄\n" #. Doesn't exist -#: ../src/sys/options.cxx:159 +#: ../src/sys/options.cxx:172 #, fuzzy, c++-format msgid "Option {:s}:{:s} does not exist" msgstr "選項{:s}:{:s}不存在" -#: ../include/bout/options.hxx:828 +#: ../include/bout/options.hxx:904 #, c++-format msgid "" "Options: Setting a value from same source ({:s}) to new value '{:s}' - old " "value was '{:s}'." msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:552 +#: ../src/mesh/impls/bout/boutmesh.cxx:588 msgid "Possible boundary regions are: " msgstr "" -#: ../src/bout++.cxx:538 +#: ../src/bout++.cxx:545 #, c++-format msgid "" "Processor number: {:d} of {:d}\n" "\n" msgstr "" -#: ../src/mesh/mesh.cxx:609 +#: ../src/mesh/mesh.cxx:642 #, c++-format msgid "Registered region 2D {:s}" msgstr "" -#: ../src/mesh/mesh.cxx:599 +#: ../src/mesh/mesh.cxx:632 #, c++-format msgid "Registered region 3D {:s}" msgstr "" -#: ../src/mesh/mesh.cxx:619 +#: ../src/mesh/mesh.cxx:652 #, c++-format msgid "Registered region Perp {:s}" msgstr "" -#: ../src/bout++.cxx:529 +#: ../src/bout++.cxx:536 #, fuzzy, c++-format msgid "Revision: {:s}\n" msgstr "版: {:s}\n" -#: ../src/solver/solver.cxx:581 +#: ../src/solver/solver.cxx:587 msgid "Run time : " msgstr "計算時間" #. / Run the solver -#: ../src/solver/solver.cxx:525 +#: ../src/solver/solver.cxx:533 msgid "" "Running simulation\n" "\n" @@ -718,7 +719,7 @@ msgstr "" msgid "Signal" msgstr "" -#: ../src/bout++.cxx:865 +#: ../src/bout++.cxx:876 msgid "" "Sim Time | RHS evals | Wall Time | Calc Inv Comm I/O SOLVER\n" "\n" @@ -727,7 +728,7 @@ msgstr "" "間整合\n" "\n" -#: ../src/bout++.cxx:868 +#: ../src/bout++.cxx:879 msgid "" "Sim Time | RHS_e evals | RHS_I evals | Wall Time | Calc Inv " "Comm I/O SOLVER\n" @@ -737,51 +738,51 @@ msgstr "" "通訊 輸入輸出 時間整合\n" "\n" -#: ../src/solver/solver.cxx:506 +#: ../src/solver/solver.cxx:514 #, c++-format msgid "Solver running for {:d} outputs with monitor timestep of {:e}\n" msgstr "" -#: ../src/solver/solver.cxx:502 +#: ../src/solver/solver.cxx:510 #, c++-format msgid "Solver running for {:d} outputs with output timestep of {:e}\n" msgstr "" -#: ../src/solver/solver.cxx:781 +#: ../src/solver/solver.cxx:788 #, c++-format msgid "" "Solver::addMonitor: Cannot reduce timestep (from {:g} to {:g}) after init is " "called!" msgstr "" -#: ../src/solver/solver.cxx:1281 +#: ../src/solver/solver.cxx:1289 #, c++-format msgid "" "Time derivative at wrong location - Field is at {:s}, derivative is at {:s} " "for field '{:s}'\n" msgstr "" -#: ../src/solver/solver.cxx:1480 +#: ../src/solver/solver.cxx:1494 #, c++-format msgid "Time derivative for variable '{:s}' not set" msgstr "" -#: ../src/mesh/mesh.cxx:605 +#: ../src/mesh/mesh.cxx:638 #, c++-format msgid "Trying to add an already existing region {:s} to regionMap2D" msgstr "" -#: ../src/mesh/mesh.cxx:595 +#: ../src/mesh/mesh.cxx:614 #, c++-format msgid "Trying to add an already existing region {:s} to regionMap3D" msgstr "" -#: ../src/mesh/mesh.cxx:616 +#: ../src/mesh/mesh.cxx:649 #, c++-format msgid "Trying to add an already existing region {:s} to regionMapPerp" msgstr "" -#: ../src/sys/options.cxx:99 ../src/sys/options.cxx:138 +#: ../src/sys/options.cxx:112 ../src/sys/options.cxx:151 #, c++-format msgid "" "Trying to index Option '{0}' with '{1}', but '{0}' is a value, not a " @@ -790,37 +791,37 @@ msgid "" "rename one of them.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:1462 +#: ../src/mesh/coordinates.cxx:1464 msgid "" "Unrecognised paralleltransform option.\n" "Valid choices are 'identity', 'shifted', 'fci'" msgstr "" -#: ../src/sys/options.cxx:872 +#: ../src/sys/options.cxx:899 msgid "Unused options:\n" msgstr "" -#: ../src/bout++.cxx:439 +#: ../src/bout++.cxx:446 #, c++-format msgid "Usage is {:s} -d \n" msgstr "" -#: ../src/bout++.cxx:448 +#: ../src/bout++.cxx:455 #, c++-format msgid "Usage is {:s} -f \n" msgstr "" -#: ../src/bout++.cxx:466 +#: ../src/bout++.cxx:473 #, c++-format msgid "Usage is {:s} -l \n" msgstr "" -#: ../src/bout++.cxx:457 +#: ../src/bout++.cxx:464 #, c++-format msgid "Usage is {:s} -o \n" msgstr "" -#: ../src/bout++.cxx:353 +#: ../src/bout++.cxx:360 #, c++-format msgid "Usage is {} {} \n" msgstr "" @@ -831,7 +832,7 @@ msgstr "" #. Print help message -- note this will be displayed once per processor as we've not #. started MPI yet. -#: ../src/bout++.cxx:367 +#: ../src/bout++.cxx:374 #, c++-format msgid "" "Usage: {:s} [-d ] [-f ] [restart [append]] " @@ -839,94 +840,99 @@ msgid "" msgstr "" #. restart file should be written by physics model -#: ../src/solver/solver.cxx:921 +#: ../src/solver/solver.cxx:927 msgid "User signalled to quit. Returning\n" msgstr "" -#: ../src/sys/options.cxx:373 +#: ../src/sys/options.cxx:486 +#, fuzzy, c++-format +msgid "Value for option {:s} = {:e} is not a bool" +msgstr "\"{:s}\" 不是目錄\n" + +#: ../src/sys/options.cxx:426 #, c++-format msgid "Value for option {:s} = {:e} is not an integer" msgstr "" -#: ../src/sys/options.cxx:408 +#: ../src/sys/options.cxx:456 #, c++-format msgid "Value for option {:s} cannot be converted to a BoutReal" msgstr "" -#: ../src/sys/options.cxx:581 +#: ../src/sys/options.cxx:623 #, c++-format msgid "Value for option {:s} cannot be converted to a Field2D" msgstr "" -#: ../src/sys/options.cxx:529 +#: ../src/sys/options.cxx:571 #, c++-format msgid "Value for option {:s} cannot be converted to a Field3D" msgstr "" -#: ../src/sys/options.cxx:663 +#: ../src/sys/options.cxx:705 #, c++-format msgid "Value for option {:s} cannot be converted to a FieldPerp" msgstr "" -#: ../src/sys/options.cxx:451 +#: ../src/sys/options.cxx:491 #, c++-format msgid "Value for option {:s} cannot be converted to a bool" msgstr "" -#: ../src/sys/options.cxx:709 +#: ../src/sys/options.cxx:751 #, c++-format msgid "Value for option {:s} cannot be converted to an Array" msgstr "" -#: ../src/sys/options.cxx:736 +#: ../src/sys/options.cxx:773 #, c++-format msgid "Value for option {:s} cannot be converted to an Matrix" msgstr "" -#: ../src/sys/options.cxx:763 +#: ../src/sys/options.cxx:795 #, c++-format msgid "Value for option {:s} cannot be converted to an Tensor" msgstr "" #. Another type which can't be converted -#: ../src/sys/options.cxx:365 +#: ../src/sys/options.cxx:418 #, c++-format msgid "Value for option {:s} is not an integer" msgstr "" -#: ../src/solver/solver.cxx:1232 ../src/solver/solver.cxx:1238 +#: ../src/solver/solver.cxx:1240 ../src/solver/solver.cxx:1246 #, c++-format msgid "Variable '{:s}' not initialised" msgstr "" -#: ../src/mesh/impls/bout/boutmesh.cxx:431 +#: ../src/mesh/impls/bout/boutmesh.cxx:467 #, c++-format msgid "" "WARNING: Number of toroidal points should be 2^n for efficient FFT " "performance -- consider changing MZ ({:d}) if using FFTs\n" msgstr "" -#: ../src/mesh/coordinates.cxx:633 +#: ../src/mesh/coordinates.cxx:635 msgid "WARNING: extrapolating input mesh quantities into x-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:410 +#: ../src/mesh/coordinates.cxx:412 msgid "" "WARNING: extrapolating input mesh quantities into x-boundary cells. Set " "option extrapolate_x=false to disable this.\n" msgstr "" -#: ../src/mesh/coordinates.cxx:638 +#: ../src/mesh/coordinates.cxx:640 msgid "WARNING: extrapolating input mesh quantities into y-boundary cells\n" msgstr "" -#: ../src/mesh/coordinates.cxx:415 +#: ../src/mesh/coordinates.cxx:417 msgid "" "WARNING: extrapolating input mesh quantities into y-boundary cells. Set " "option extrapolate_y=false to disable this.\n" msgstr "" -#: ../src/bout++.cxx:814 +#: ../src/bout++.cxx:825 msgid "Wall time limit in hours. By default (< 0), no limit" msgstr "" @@ -936,10 +942,18 @@ msgid "Writing options to file {:s}\n" msgstr "寫選項到文件 " #. / The source label given to default values -#: ../src/sys/options.cxx:15 +#: ../src/sys/options.cxx:34 msgid "default" msgstr "默认设置" +#, fuzzy, c++-format +#~ msgid "\tOpenMP parallelisation {}" +#~ msgstr "\tOpenMP並行化已禁用\n" + +#, fuzzy, c++-format +#~ msgid "\tOption '{:s}': Boolean expected. Got '{:s}'\n" +#~ msgstr "\t選項 '{:s}': 布爾預期. 拿到 '{:s}'\n" + #~ msgid "\tChecking disabled\n" #~ msgstr "\t測試關掉\n" @@ -947,13 +961,5 @@ msgstr "默认设置" #~ msgid "\tChecking enabled, level {:d}\n" #~ msgstr "\t測試打開,级别 {:d}\n" -#, fuzzy -#~ msgid "\tOpenMP parallelisation enabled, using {:d} threads\n" -#~ msgstr "\t啟用OpenMP並行化。 使用{:d}個線程\n" - -#, fuzzy -#~ msgid "Option {:s} is not a section" -#~ msgstr "\"{:s}\" 不是目錄\n" - #~ msgid "Error encountered during initialisation\n" #~ msgstr "啟動時遇到錯誤\n" diff --git a/manual/RELEASE_HOWTO.md b/manual/RELEASE_HOWTO.md index d8ced2afb5..d0a6ddb231 100644 --- a/manual/RELEASE_HOWTO.md +++ b/manual/RELEASE_HOWTO.md @@ -29,11 +29,10 @@ Before merging PR: - Be aware that this *will* update the timestamps and *possibly* reorder file paths in the .po and .pot files - [ ] Update [`CHANGELOG.md`][changelog]: - - Run [bout-changelog-generator.py LAST_RELEASE NEXT_RELEASE][bin/bout-changelog-generator.py] + - Run [`bout-changelog-generator.py LAST_RELEASE NEXT_RELEASE`][bin/bout-changelog-generator.py] - See the docs for how to get the token -- [ ] Get list of authors: - - [ ] `git log --format='%aN' | sort | uniq` - - [ ] Compare to list in [`CITATION.cff`][citation], add new authors +- [ ] Run [`update_citations.py`][bin/update_citations.py] to add new + authors to [`CITATION.cff`](CITATION.cff) - [ ] Prep a new Zenodo release: - https://doi.org/10.5281/zenodo.1423212 - "New Version" @@ -44,13 +43,7 @@ Before merging PR: - [ ] Change DOI in [`README.md`][README] to new DOI - [ ] Change date-released in [`CITATION.cff`][citation] - [ ] Check `abidiff` to see if `soname` needs bumping in `makefile`: -- [ ] Change version number, removing prerelease tag in: - - [ ] [`configure.ac`][configure]: `AC_INIT` - - [ ] [`CITATION.cff`][citation]: `version` - - [ ] [`manual/sphinx/conf.py`][sphinx_conf]: `version` and `release` - - [ ] [`manual/doxygen/Doxyfile_readthedocs`][Doxyfile_readthedocs]: `PROJECT_NUMBER` - - [ ] [`manual/doxygen/Doxyfile`][Doxyfile]: `PROJECT_NUMBER` - - [ ] [`CMakeLists.txt`][CMakeLists]: `_bout_previous_version`, `_bout_next_version` +- [ ] Run [`update_version_number.py LAST_RELEASE NEXT_RELEASE`][bin/update_version_number.py] - [ ] Update what version of PETSc and SUNDIALS we support (upper bound) diff --git a/manual/doxygen/Doxyfile b/manual/doxygen/Doxyfile index 0e3c6f6945..e7998854b0 100644 --- a/manual/doxygen/Doxyfile +++ b/manual/doxygen/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = BOUT++ # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 5.1.1 +PROJECT_NUMBER = 5.2.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/manual/doxygen/Doxyfile_readthedocs b/manual/doxygen/Doxyfile_readthedocs index 5c67187248..73060bb6b4 100644 --- a/manual/doxygen/Doxyfile_readthedocs +++ b/manual/doxygen/Doxyfile_readthedocs @@ -38,7 +38,7 @@ PROJECT_NAME = BOUT++ # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 5.1.1 +PROJECT_NUMBER = 5.2.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/manual/sphinx/conf.py b/manual/sphinx/conf.py index 55d059feba..3aa6e94dc3 100755 --- a/manual/sphinx/conf.py +++ b/manual/sphinx/conf.py @@ -184,9 +184,9 @@ def __getattr__(cls, name): # built documents. # # The short X.Y version. -version = "5.1" +version = "5.2" # The full version, including alpha/beta/rc tags. -release = "5.1.1" +release = "5.2.0" # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/manual/sphinx/user_docs/boundary_options.rst b/manual/sphinx/user_docs/boundary_options.rst index e2d8f28b3f..548a3ae339 100644 --- a/manual/sphinx/user_docs/boundary_options.rst +++ b/manual/sphinx/user_docs/boundary_options.rst @@ -502,7 +502,7 @@ geometries, as flux coordinate independent (FCI) method:: void rhs() { BoutReal totalFlux = 0; yboundary.iter_pnts([&](auto& pnt) { - BoutReal flux = pnt.interpolate_sheath_o1(N) * pnt.interpolate_sheath_o1(V); + BoutReal flux = pnt.interpolate_sheath_o2(N) * pnt.interpolate_sheath_o2(V); }); } @@ -536,7 +536,7 @@ Here is a short summary of some members of ``pnt``, where ``f`` is a : * - ``pnt.yprev(f)`` - Returns the value at the second to last point in the domain, if it is valid. NB: this point may not be valid. - * - ``pnt.interpolate_sheath_o1(f)`` + * - ``pnt.interpolate_sheath_o2(f)`` - Returns the value at the boundary, assuming the bounday value has been set * - ``pnt.extrapolate_sheath_o1(f)`` - Returns the value at the boundary, extrapolating from the bulk, first order diff --git a/output.make b/output.make deleted file mode 100644 index eae6b1be64..0000000000 --- a/output.make +++ /dev/null @@ -1,22 +0,0 @@ -BOUT_TOP ?= . - -include make.config - -# These expand to literals of the same name, which are then -# set in the bout.config script. This enables -# the final paths to the include and lib files to be set -# in the make/make install targets - -BOUT_INCLUDE_PATH="\$$BOUT_INCLUDE_PATH" -BOUT_LIB_PATH="\$$BOUT_LIB_PATH" -MPARK_VARIANT_INCLUDE_PATH="\$$MPARK_VARIANT_INCLUDE_PATH" -FMT_INCLUDE_PATH="\$$FMT_INCLUDE_PATH" - -.PHONY: cflags -cflags: - @echo $(BOUT_INCLUDE) $(BOUT_FLAGS) - -.PHONY: ldflags -ldflags: - @echo $(LDFLAGS) $(BOUT_LIBS) - diff --git a/requirements.txt b/requirements.txt index 52d3076d58..078eecac6d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,5 @@ scipy>=1.14.1 netcdf4>=1.7.1 matplotlib>=3.7.0 Cython>=3.0.0 -boututils>=0.2.1 -boutdata>=0.2.1 +boutdata>=0.3.0 zoidberg>=0.2.2 diff --git a/requirements_maint.txt b/requirements_maint.txt index 9f4ddc3699..b1d9db5ff8 100644 --- a/requirements_maint.txt +++ b/requirements_maint.txt @@ -1,3 +1,3 @@ -pygithub~=2.4 +pygithub~=2.8 ruamel-yaml~=0.18 Unidecode~=1.3 diff --git a/src/bout++.cxx b/src/bout++.cxx index 6de1c5713b..48ab96298b 100644 --- a/src/bout++.cxx +++ b/src/bout++.cxx @@ -67,11 +67,10 @@ const char DEFAULT_DIR[] = "data"; #include #include +#include #include #include -#include - // Value passed at compile time // Used for MD5SUM, BOUT_LOCALE_PATH, and REVISION #define BUILDFLAG1_(x) #x @@ -81,12 +80,6 @@ const char DEFAULT_DIR[] = "data"; #define INDIRECT0_BOUTMAIN(...) INDIRECT1_BOUTMAIN(#__VA_ARGS__) #define STRINGIFY(a) INDIRECT0_BOUTMAIN(a) -// Define S_ISDIR if not defined by system headers (that is, MSVC) -// Taken from https://github.com/curl/curl/blob/e59540139a398dc70fde6aec487b19c5085105af/lib/curl_setup.h#L748-L751 -#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) -#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif - #ifdef _MSC_VER #include inline auto getpid() -> int { return GetCurrentProcessId(); } @@ -506,9 +499,8 @@ auto parseCommandLineArgs(int argc, char** argv) -> CommandLineArgs { } void checkDataDirectoryIsAccessible(const std::string& data_dir) { - struct stat test; - if (stat(data_dir.c_str(), &test) == 0) { - if (!S_ISDIR(test.st_mode)) { + if (std::filesystem::exists(data_dir)) { + if (!std::filesystem::is_directory(data_dir)) { throw BoutException(_("DataDir \"{:s}\" is not a directory\n"), data_dir); } } else { diff --git a/src/field/field3d.cxx b/src/field/field3d.cxx index 74a6f0853c..2fc6726ebc 100644 --- a/src/field/field3d.cxx +++ b/src/field/field3d.cxx @@ -66,7 +66,8 @@ Field3D::Field3D(Mesh* localmesh, CELL_LOC location_in, DirectionTypes direction /// later) Field3D::Field3D(const Field3D& f) : Field(f), data(f.data), yup_fields(f.yup_fields), ydown_fields(f.ydown_fields), - regionID(f.regionID) { + regionID(f.regionID), tracking_state(f.tracking_state), tracking(f.tracking), + selfname(f.selfname) { TRACE("Field3D(Field3D&)"); @@ -93,15 +94,22 @@ Field3D::Field3D(const BoutReal val, Mesh* localmesh) : Field3D(localmesh) { TRACE("Field3D: Copy constructor from value"); *this = val; -#if BOUT_USE_FCI_AUTOMAGIC +} + +Field3DParallel::Field3DParallel(const BoutReal val, Mesh* localmesh) + : Field3D(localmesh) { + + TRACE("Field3DParallel: Copy constructor from value"); + + *this = val; if (this->isFci()) { splitParallelSlices(); for (size_t i = 0; i < numberParallelSlices(); ++i) { yup(i) = val; ydown(i) = val; } + resetRegionParallel(); } -#endif } Field3D::Field3D(Array data_in, Mesh* localmesh, CELL_LOC datalocation, @@ -158,11 +166,8 @@ void Field3D::splitParallelSlices() { // ParallelTransform, so we don't need a full constructor yup_fields.emplace_back(fieldmesh); ydown_fields.emplace_back(fieldmesh); - if (isFci()) { - yup_fields[i].setRegion(fmt::format("RGN_YPAR_{:+d}", i + 1)); - ydown_fields[i].setRegion(fmt::format("RGN_YPAR_{:+d}", -i - 1)); - } } + resetRegionParallel(); } void Field3D::splitParallelSlicesAndAllocate() { splitParallelSlices(); @@ -361,19 +366,34 @@ Field3D& Field3D::operator=(const BoutReal val) { TRACE("Field3D = BoutReal"); track(val, "operator="); -#if BOUT_USE_FCI_AUTOMAGIC - if (isFci() && hasParallelSlices()) { + // Delete existing parallel slices. We don't copy parallel slices, so any + // that currently exist will be incorrect. + clearParallelSlices(); + resetRegion(); + + allocate(); + + BOUT_FOR(i, getRegion("RGN_ALL")) { (*this)[i] = val; } + this->name = "BR"; + + return *this; +} + +Field3DParallel& Field3DParallel::operator=(const BoutReal val) { + TRACE("Field3DParallel = BoutReal"); + track(val, "operator="); + + if (isFci()) { + if (!hasParallelSlices()) { + splitParallelSlices(); + } for (size_t i = 0; i < numberParallelSlices(); ++i) { yup(i) = val; ydown(i) = val; } } -#else - // Delete existing parallel slices. We don't copy parallel slices, so any - // that currently exist will be incorrect. - clearParallelSlices(); -#endif resetRegion(); + resetRegionParallel(); allocate(); @@ -386,11 +406,6 @@ Field3D& Field3D::operator=(const BoutReal val) { Field3D& Field3D::calcParallelSlices() { ASSERT2(allowCalcParallelSlices); getCoordinates()->getParallelTransform().calcParallelSlices(*this); -#if BOUT_USE_FCI_AUTOMAGIC - if (this->isFci()) { - this->applyParallelBoundary("parallel_neumann_o2"); - } -#endif return *this; } @@ -514,7 +529,7 @@ void Field3D::setBoundaryTo(const Field3D& f3d, bool copyParallelSlices) { for (auto& region : fieldmesh->getBoundariesPar()) { for (const auto& pnt : *region) { // Interpolate midpoint value in f3d - const BoutReal val = pnt.interpolate_sheath_o1(f3d); + const BoutReal val = pnt.interpolate_sheath_o2(f3d); // Set the same boundary value in this field pnt.dirichlet_o1(*this, val); } @@ -556,6 +571,21 @@ void Field3D::applyParallelBoundary() { } } +void Field3D::applyParallelBoundaryWithDefault(const std::string& condition) { + + checkData(*this); + ASSERT1(hasParallelSlices()); + + // Apply boundary to this field + if (getBoundaryOpPars().empty()) { + applyParallelBoundary(condition); + } else { + for (const auto& bndry : getBoundaryOpPars()) { + bndry->apply(*this); + } + } +} + void Field3D::applyParallelBoundary(BoutReal t) { TRACE("Field3D::applyParallelBoundary(t)"); @@ -896,6 +926,10 @@ void swap(Field3D& first, Field3D& second) noexcept { swap(first.deriv, second.deriv); swap(first.yup_fields, second.yup_fields); swap(first.ydown_fields, second.ydown_fields); + swap(first.regionID, second.regionID); + swap(first.tracking_state, second.tracking_state); + swap(first.tracking, second.tracking); + swap(first.selfname, second.selfname); } const Region& @@ -911,6 +945,14 @@ void Field3D::setRegion(const std::string& region_name) { } void Field3D::resetRegion() { regionID.reset(); }; +void Field3D::resetRegionParallel() { + if (isFci()) { + for (int i = 0; i < fieldmesh->ystart; ++i) { + yup_fields[i].setRegion(fmt::format("RGN_YPAR_{:+d}", i + 1)); + ydown_fields[i].setRegion(fmt::format("RGN_YPAR_{:+d}", -i - 1)); + } + } +} void Field3D::setRegion(size_t id) { regionID = id; }; void Field3D::setRegion(std::optional id) { regionID = id; }; @@ -941,6 +983,7 @@ Options* Field3D::track(const T& change, std::string operation) { return nullptr; } +template Options* Field3D::track(const Field3DParallel&, std::string); template Options* Field3D::track(const Field3D&, std::string); template Options* Field3D::track(const Field2D&, std::string); template Options* Field3D::track(const FieldPerp&, std::string); @@ -957,3 +1000,29 @@ Options* Field3D::track(const BoutReal& change, std::string operation) { } return nullptr; } + +void Field3DParallel::ensureFieldAligned() { + if (isFci()) { + ASSERT2(hasParallelSlices()); + if (fieldmesh != nullptr) { + for (int i = 0; i < fieldmesh->ystart; ++i) { + ASSERT2(yup_fields[i].getRegionID().has_value()); + ASSERT2(ydown_fields[i].getRegionID().has_value()); + } + } + } +} + +Field3DParallel& Field3DParallel::allocate() { + Field3D::allocate(); + if (isFci()) { + ASSERT2(hasParallelSlices()); + if (fieldmesh != nullptr) { + for (int i = 0; i < fieldmesh->ystart; ++i) { + yup_fields[i].allocate(); + ydown_fields[i].allocate(); + } + } + } + return *this; +} diff --git a/src/field/gen_fieldops.jinja b/src/field/gen_fieldops.jinja index 88e877c197..66b5103247 100644 --- a/src/field/gen_fieldops.jinja +++ b/src/field/gen_fieldops.jinja @@ -8,45 +8,29 @@ checkData({{lhs.name}}); checkData({{rhs.name}}); - {% if out == "Field3D" %} - {% if lhs == rhs == "Field3D" %} + {% if out.region_type == "3D" %} + {% if lhs.region_type == rhs.region_type == "3D" %} {{out.name}}.setRegion({{lhs.name}}.getMesh()->getCommonRegion({{lhs.name}}.getRegionID(), {{rhs.name}}.getRegionID())); -#if BOUT_USE_FCI_AUTOMAGIC - if ({{lhs.name}}.isFci() and {{lhs.name}}.hasParallelSlices() and {{rhs.name}}.hasParallelSlices()) { - {{out.name}}.splitParallelSlices(); - for (size_t i{0} ; i < {{lhs.name}}.numberParallelSlices() ; ++i) { - {{out.name}}.yup(i) = {{lhs.name}}.yup(i) {{operator}} {{rhs.name}}.yup(i); - {{out.name}}.ydown(i) = {{lhs.name}}.ydown(i) {{operator}} {{rhs.name}}.ydown(i); - } - } -#endif - {% elif lhs == "Field3D" %} + {% elif lhs.region_type == "3D" %} {{out.name}}.setRegion({{lhs.name}}.getRegionID()); - {% if rhs == "BoutReal" %} -#if BOUT_USE_FCI_AUTOMAGIC - if ({{lhs.name}}.isFci() and {{lhs.name}}.hasParallelSlices()) { - {{out.name}}.splitParallelSlices(); - for (size_t i{0} ; i < {{lhs.name}}.numberParallelSlices() ; ++i) { - {{out.name}}.yup(i) = {{lhs.name}}.yup(i) {{operator}} {{rhs.name}}; - {{out.name}}.ydown(i) = {{lhs.name}}.ydown(i) {{operator}} {{rhs.name}}; - } - } -#endif - {% endif %} - {% elif rhs == "Field3D" %} + {% elif rhs.region_type == "3D" %} {{out.name}}.setRegion({{rhs.name}}.getRegionID()); - {% if lhs == "BoutReal" %} -#if BOUT_USE_FCI_AUTOMAGIC - if ({{rhs.name}}.isFci() and {{rhs.name}}.hasParallelSlices()) { + {% endif %} + {% if out == "Field3DParallel" %} + if ({{out.name}}.isFci()) { + {{ lhs.assertParallelSlices }} + {{ rhs.assertParallelSlices }} {{out.name}}.splitParallelSlices(); - for (size_t i{0} ; i < {{rhs.name}}.numberParallelSlices() ; ++i) { - {{out.name}}.yup(i) = {{lhs.name}} {{operator}} {{rhs.name}}.yup(i); - {{out.name}}.ydown(i) = {{lhs.name}} {{operator}} {{rhs.name}}.ydown(i); + {% if lhs.region_type == "3D" %} + for (size_t i{0} ; i < {{lhs.name}}.numberParallelSlices() ; ++i) { + {% else %} + for (size_t i{0} ; i < {{rhs.name}}.numberParallelSlices() ; ++i) { + {% endif %} + {{out.name}}.yup(i) = {{lhs.yup}} {{operator}} {{rhs.yup}}; + {{out.name}}.ydown(i) = {{lhs.ydown}} {{operator}} {{rhs.ydown}}; } } -#endif - {% endif %} {% endif %} {% endif %} @@ -110,29 +94,26 @@ ASSERT1_FIELDS_COMPATIBLE(*this, rhs); {% endif %} - {% if (lhs == "Field3D") %} - // Delete existing parallel slices. We don't copy parallel slices, so any + {% if lhs == "Field3D" %} + // Delete existing parallel slices. We don't update parallel slices, so any // that currently exist will be incorrect. - {% if (rhs == "Field3D" or rhs == "BoutReal") %} -#if BOUT_USE_FCI_AUTOMAGIC - if (this->isFci() and this->hasParallelSlices() {% if rhs == "Field3D" %} and {{rhs.name}}.hasParallelSlices() {% endif %}) { + clearParallelSlices(); + {% endif %} + {% if lhs == "Field3DParallel" and (rhs.region_type == "3D" or rhs == "BoutReal") %} + if (this->isFci()) { for (size_t i{0} ; i < yup_fields.size() ; ++i) { yup(i) {{operator}}= {{rhs.name}}{% if rhs == "Field3D" %}.yup(i){% endif %}; ydown(i) {{operator}}= {{rhs.name}}{% if rhs == "Field3D" %}.ydown(i){% endif %}; } - } else -#endif - {% endif %} - { + } else { clearParallelSlices(); } - {% endif %} checkData(*this); checkData({{rhs.name}}); - {% if lhs == rhs == "Field3D" %} - regionID = fieldmesh->getCommonRegion(regionID, {{rhs.name}}.regionID); + {% if lhs.region_type == rhs.region_type == "3D" %} + regionID = fieldmesh->getCommonRegion(regionID, {{rhs.name}}.getRegionID()); {% endif %} @@ -176,7 +157,7 @@ } {% endif %} - {% if lhs == "Field3D" %} + {% if lhs.region_type == "3D" %} track(rhs, "operator{{operator}}="); {% endif %} #if BOUT_USE_TRACK @@ -186,7 +167,7 @@ checkData(*this); } else { - {% if lhs == "Field3D" %} + {% if lhs.region_type == "3D" %} track(rhs, "operator{{operator}}="); {% endif %} (*this) = (*this) {{operator}} {{rhs.name}}; diff --git a/src/field/gen_fieldops.py b/src/field/gen_fieldops.py index 29631ff7aa..64d3771c55 100755 --- a/src/field/gen_fieldops.py +++ b/src/field/gen_fieldops.py @@ -54,15 +54,13 @@ def smart_open(filename, mode="r"): # The arthimetic operators -# OrderedDict to (try to) ensure consistency between python 2 & 3 -operators = OrderedDict( - [ - ("*", "multiplication"), - ("/", "division"), - ("+", "addition"), - ("-", "subtraction"), - ] -) +operators = { + "*": "multiplication", + "/": "division", + "+": "addition", + "-": "subtraction", +} + header = """// This file is autogenerated - see gen_fieldops.py #include @@ -71,6 +69,7 @@ def smart_open(filename, mode="r"): #include #include #include +#include """ @@ -104,7 +103,7 @@ def __init__( self.mixed_base_ind_var = mixed_base_ind_var # Note region_type isn't actually used currently but # may be useful in future. - if self.field_type == "Field3D": + if "Field3D" in self.field_type: self.region_type = "3D" elif self.field_type == "Field2D": self.region_type = "2D" @@ -158,6 +157,28 @@ def base_index(self): else: return "{self.name}[{self.mixed_base_ind_var}]".format(self=self) + @property + def yup(self): + """Returns {{name}}.yup(i) if it is a field with parallel slices. + If it is BoutReal just {{name}}""" + if self.field_type == "BoutReal": + return "{self.name}".format(self=self) + return "{self.name}.yup(i)".format(self=self) + + @property + def ydown(self): + """Returns {{name}}.ydown(i) if it is a field with parallel slices. + If it is BoutReal just {{name}}""" + if self.field_type == "BoutReal": + return "{self.name}".format(self=self) + return "{self.name}.ydown(i)".format(self=self) + + @property + def assertParallelSlices(self): + if self.field_type == "BoutReal": + return "" + return f"ASSERT2({self.name}.hasParallelSlices());" + def __eq__(self, other): try: return self.field_type == other.field_type @@ -184,6 +205,8 @@ def returnType(f1, f2): return copy(f1) elif f1 == "FieldPerp" or f2 == "FieldPerp": return copy(fieldPerp) + elif f1 == "Field3DParallel" or f2 == "Field3DParallel": + return copy(field3DPar) else: return copy(field3D) @@ -219,7 +242,6 @@ def returnType(f1, f2): region_loop = "BOUT_FOR" # Declare what fields we currently support: - # Field perp is currently missing field3D = Field( "Field3D", ["x", "y", "z"], @@ -227,6 +249,13 @@ def returnType(f1, f2): jz_var=jz_var, mixed_base_ind_var=mixed_base_ind_var, ) + field3DPar = Field( + "Field3DParallel", + ["x", "y", "z"], + index_var=index_var, + jz_var=jz_var, + mixed_base_ind_var=mixed_base_ind_var, + ) field2D = Field( "Field2D", ["x", "y"], @@ -249,7 +278,8 @@ def returnType(f1, f2): mixed_base_ind_var=mixed_base_ind_var, ) - fields = [field3D, field2D, fieldPerp, boutreal] + fields = (field3D, field2D, fieldPerp, boutreal) + fields2 = (field3D, field3DPar, boutreal) with smart_open(args.filename, "w") as f: f.write(header) @@ -259,10 +289,16 @@ def returnType(f1, f2): template = env.get_template("gen_fieldops.jinja") - for lhs, rhs in itertools.product(fields, fields): - # We don't have to define BoutReal BoutReal operations - if lhs == rhs == "BoutReal": + # We don't have to define BoutReal BoutReal operations + done = [(boutreal, boutreal)] + for lhs, rhs in itertools.chain( + itertools.product(fields, fields), + itertools.product(fields2, fields2), + ): + if (lhs, rhs) in done: continue + done.append((lhs, rhs)) + rhs = copy(rhs) lhs = copy(lhs) diff --git a/src/field/generated_fieldops.cxx b/src/field/generated_fieldops.cxx index 75d2ede82d..5f66172302 100644 --- a/src/field/generated_fieldops.cxx +++ b/src/field/generated_fieldops.cxx @@ -5,6 +5,7 @@ #include #include #include +#include // Provide the C++ wrapper for multiplication of Field3D and Field3D Field3D operator*(const Field3D& lhs, const Field3D& rhs) { @@ -15,15 +16,6 @@ Field3D operator*(const Field3D& lhs, const Field3D& rhs) { checkData(rhs); result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); -#if BOUT_USE_FCI_AUTOMAGIC - if (lhs.isFci() and lhs.hasParallelSlices() and rhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs.yup(i) * rhs.yup(i); - result.ydown(i) = lhs.ydown(i) * rhs.ydown(i); - } - } -#endif BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] * rhs[index]; @@ -43,24 +35,13 @@ Field3D& Field3D::operator*=(const Field3D& rhs) { if (data.unique()) { ASSERT1_FIELDS_COMPATIBLE(*this, rhs); - // Delete existing parallel slices. We don't copy parallel slices, so any -// that currently exist will be incorrect. -#if BOUT_USE_FCI_AUTOMAGIC - if (this->isFci() and this->hasParallelSlices() and rhs.hasParallelSlices()) { - for (size_t i{0}; i < yup_fields.size(); ++i) { - yup(i) *= rhs.yup(i); - ydown(i) *= rhs.ydown(i); - } - } else -#endif - { - clearParallelSlices(); - } - + // Delete existing parallel slices. We don't update parallel slices, so any + // that currently exist will be incorrect. + clearParallelSlices(); checkData(*this); checkData(rhs); - regionID = fieldmesh->getCommonRegion(regionID, rhs.regionID); + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] *= rhs[index]; } @@ -87,15 +68,6 @@ Field3D operator/(const Field3D& lhs, const Field3D& rhs) { checkData(rhs); result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); -#if BOUT_USE_FCI_AUTOMAGIC - if (lhs.isFci() and lhs.hasParallelSlices() and rhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs.yup(i) / rhs.yup(i); - result.ydown(i) = lhs.ydown(i) / rhs.ydown(i); - } - } -#endif BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] / rhs[index]; @@ -115,24 +87,13 @@ Field3D& Field3D::operator/=(const Field3D& rhs) { if (data.unique()) { ASSERT1_FIELDS_COMPATIBLE(*this, rhs); - // Delete existing parallel slices. We don't copy parallel slices, so any -// that currently exist will be incorrect. -#if BOUT_USE_FCI_AUTOMAGIC - if (this->isFci() and this->hasParallelSlices() and rhs.hasParallelSlices()) { - for (size_t i{0}; i < yup_fields.size(); ++i) { - yup(i) /= rhs.yup(i); - ydown(i) /= rhs.ydown(i); - } - } else -#endif - { - clearParallelSlices(); - } - + // Delete existing parallel slices. We don't update parallel slices, so any + // that currently exist will be incorrect. + clearParallelSlices(); checkData(*this); checkData(rhs); - regionID = fieldmesh->getCommonRegion(regionID, rhs.regionID); + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] /= rhs[index]; } @@ -159,15 +120,6 @@ Field3D operator+(const Field3D& lhs, const Field3D& rhs) { checkData(rhs); result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); -#if BOUT_USE_FCI_AUTOMAGIC - if (lhs.isFci() and lhs.hasParallelSlices() and rhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs.yup(i) + rhs.yup(i); - result.ydown(i) = lhs.ydown(i) + rhs.ydown(i); - } - } -#endif BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] + rhs[index]; @@ -187,24 +139,13 @@ Field3D& Field3D::operator+=(const Field3D& rhs) { if (data.unique()) { ASSERT1_FIELDS_COMPATIBLE(*this, rhs); - // Delete existing parallel slices. We don't copy parallel slices, so any -// that currently exist will be incorrect. -#if BOUT_USE_FCI_AUTOMAGIC - if (this->isFci() and this->hasParallelSlices() and rhs.hasParallelSlices()) { - for (size_t i{0}; i < yup_fields.size(); ++i) { - yup(i) += rhs.yup(i); - ydown(i) += rhs.ydown(i); - } - } else -#endif - { - clearParallelSlices(); - } - + // Delete existing parallel slices. We don't update parallel slices, so any + // that currently exist will be incorrect. + clearParallelSlices(); checkData(*this); checkData(rhs); - regionID = fieldmesh->getCommonRegion(regionID, rhs.regionID); + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] += rhs[index]; } @@ -231,15 +172,6 @@ Field3D operator-(const Field3D& lhs, const Field3D& rhs) { checkData(rhs); result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); -#if BOUT_USE_FCI_AUTOMAGIC - if (lhs.isFci() and lhs.hasParallelSlices() and rhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs.yup(i) - rhs.yup(i); - result.ydown(i) = lhs.ydown(i) - rhs.ydown(i); - } - } -#endif BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] - rhs[index]; @@ -259,24 +191,13 @@ Field3D& Field3D::operator-=(const Field3D& rhs) { if (data.unique()) { ASSERT1_FIELDS_COMPATIBLE(*this, rhs); - // Delete existing parallel slices. We don't copy parallel slices, so any -// that currently exist will be incorrect. -#if BOUT_USE_FCI_AUTOMAGIC - if (this->isFci() and this->hasParallelSlices() and rhs.hasParallelSlices()) { - for (size_t i{0}; i < yup_fields.size(); ++i) { - yup(i) -= rhs.yup(i); - ydown(i) -= rhs.ydown(i); - } - } else -#endif - { - clearParallelSlices(); - } - + // Delete existing parallel slices. We don't update parallel slices, so any + // that currently exist will be incorrect. + clearParallelSlices(); checkData(*this); checkData(rhs); - regionID = fieldmesh->getCommonRegion(regionID, rhs.regionID); + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] -= rhs[index]; } @@ -327,10 +248,9 @@ Field3D& Field3D::operator*=(const Field2D& rhs) { if (data.unique()) { ASSERT1_FIELDS_COMPATIBLE(*this, rhs); - // Delete existing parallel slices. We don't copy parallel slices, so any + // Delete existing parallel slices. We don't update parallel slices, so any // that currently exist will be incorrect. - { clearParallelSlices(); } - + clearParallelSlices(); checkData(*this); checkData(rhs); @@ -389,10 +309,9 @@ Field3D& Field3D::operator/=(const Field2D& rhs) { if (data.unique()) { ASSERT1_FIELDS_COMPATIBLE(*this, rhs); - // Delete existing parallel slices. We don't copy parallel slices, so any + // Delete existing parallel slices. We don't update parallel slices, so any // that currently exist will be incorrect. - { clearParallelSlices(); } - + clearParallelSlices(); checkData(*this); checkData(rhs); @@ -451,10 +370,9 @@ Field3D& Field3D::operator+=(const Field2D& rhs) { if (data.unique()) { ASSERT1_FIELDS_COMPATIBLE(*this, rhs); - // Delete existing parallel slices. We don't copy parallel slices, so any + // Delete existing parallel slices. We don't update parallel slices, so any // that currently exist will be incorrect. - { clearParallelSlices(); } - + clearParallelSlices(); checkData(*this); checkData(rhs); @@ -512,10 +430,9 @@ Field3D& Field3D::operator-=(const Field2D& rhs) { if (data.unique()) { ASSERT1_FIELDS_COMPATIBLE(*this, rhs); - // Delete existing parallel slices. We don't copy parallel slices, so any + // Delete existing parallel slices. We don't update parallel slices, so any // that currently exist will be incorrect. - { clearParallelSlices(); } - + clearParallelSlices(); checkData(*this); checkData(rhs); @@ -640,15 +557,6 @@ Field3D operator*(const Field3D& lhs, const BoutReal rhs) { checkData(rhs); result.setRegion(lhs.getRegionID()); -#if BOUT_USE_FCI_AUTOMAGIC - if (lhs.isFci() and lhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs.yup(i) * rhs; - result.ydown(i) = lhs.ydown(i) * rhs; - } - } -#endif BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] * rhs; @@ -667,20 +575,9 @@ Field3D& Field3D::operator*=(const BoutReal rhs) { // otherwise just call the non-inplace version if (data.unique()) { - // Delete existing parallel slices. We don't copy parallel slices, so any -// that currently exist will be incorrect. -#if BOUT_USE_FCI_AUTOMAGIC - if (this->isFci() and this->hasParallelSlices()) { - for (size_t i{0}; i < yup_fields.size(); ++i) { - yup(i) *= rhs; - ydown(i) *= rhs; - } - } else -#endif - { - clearParallelSlices(); - } - + // Delete existing parallel slices. We don't update parallel slices, so any + // that currently exist will be incorrect. + clearParallelSlices(); checkData(*this); checkData(rhs); @@ -708,15 +605,6 @@ Field3D operator/(const Field3D& lhs, const BoutReal rhs) { checkData(rhs); result.setRegion(lhs.getRegionID()); -#if BOUT_USE_FCI_AUTOMAGIC - if (lhs.isFci() and lhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs.yup(i) / rhs; - result.ydown(i) = lhs.ydown(i) / rhs; - } - } -#endif const auto tmp = 1.0 / rhs; BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { @@ -736,20 +624,9 @@ Field3D& Field3D::operator/=(const BoutReal rhs) { // otherwise just call the non-inplace version if (data.unique()) { - // Delete existing parallel slices. We don't copy parallel slices, so any -// that currently exist will be incorrect. -#if BOUT_USE_FCI_AUTOMAGIC - if (this->isFci() and this->hasParallelSlices()) { - for (size_t i{0}; i < yup_fields.size(); ++i) { - yup(i) /= rhs; - ydown(i) /= rhs; - } - } else -#endif - { - clearParallelSlices(); - } - + // Delete existing parallel slices. We don't update parallel slices, so any + // that currently exist will be incorrect. + clearParallelSlices(); checkData(*this); checkData(rhs); @@ -778,15 +655,6 @@ Field3D operator+(const Field3D& lhs, const BoutReal rhs) { checkData(rhs); result.setRegion(lhs.getRegionID()); -#if BOUT_USE_FCI_AUTOMAGIC - if (lhs.isFci() and lhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs.yup(i) + rhs; - result.ydown(i) = lhs.ydown(i) + rhs; - } - } -#endif BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] + rhs; @@ -805,20 +673,9 @@ Field3D& Field3D::operator+=(const BoutReal rhs) { // otherwise just call the non-inplace version if (data.unique()) { - // Delete existing parallel slices. We don't copy parallel slices, so any -// that currently exist will be incorrect. -#if BOUT_USE_FCI_AUTOMAGIC - if (this->isFci() and this->hasParallelSlices()) { - for (size_t i{0}; i < yup_fields.size(); ++i) { - yup(i) += rhs; - ydown(i) += rhs; - } - } else -#endif - { - clearParallelSlices(); - } - + // Delete existing parallel slices. We don't update parallel slices, so any + // that currently exist will be incorrect. + clearParallelSlices(); checkData(*this); checkData(rhs); @@ -846,15 +703,6 @@ Field3D operator-(const Field3D& lhs, const BoutReal rhs) { checkData(rhs); result.setRegion(lhs.getRegionID()); -#if BOUT_USE_FCI_AUTOMAGIC - if (lhs.isFci() and lhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs.yup(i) - rhs; - result.ydown(i) = lhs.ydown(i) - rhs; - } - } -#endif BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs[index] - rhs; @@ -873,20 +721,9 @@ Field3D& Field3D::operator-=(const BoutReal rhs) { // otherwise just call the non-inplace version if (data.unique()) { - // Delete existing parallel slices. We don't copy parallel slices, so any -// that currently exist will be incorrect. -#if BOUT_USE_FCI_AUTOMAGIC - if (this->isFci() and this->hasParallelSlices()) { - for (size_t i{0}; i < yup_fields.size(); ++i) { - yup(i) -= rhs; - ydown(i) -= rhs; - } - } else -#endif - { - clearParallelSlices(); - } - + // Delete existing parallel slices. We don't update parallel slices, so any + // that currently exist will be incorrect. + clearParallelSlices(); checkData(*this); checkData(rhs); @@ -2209,15 +2046,6 @@ Field3D operator*(const BoutReal lhs, const Field3D& rhs) { checkData(rhs); result.setRegion(rhs.getRegionID()); -#if BOUT_USE_FCI_AUTOMAGIC - if (rhs.isFci() and rhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < rhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs * rhs.yup(i); - result.ydown(i) = lhs * rhs.ydown(i); - } - } -#endif BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs * rhs[index]; @@ -2238,15 +2066,6 @@ Field3D operator/(const BoutReal lhs, const Field3D& rhs) { checkData(rhs); result.setRegion(rhs.getRegionID()); -#if BOUT_USE_FCI_AUTOMAGIC - if (rhs.isFci() and rhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < rhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs / rhs.yup(i); - result.ydown(i) = lhs / rhs.ydown(i); - } - } -#endif BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs / rhs[index]; @@ -2267,15 +2086,6 @@ Field3D operator+(const BoutReal lhs, const Field3D& rhs) { checkData(rhs); result.setRegion(rhs.getRegionID()); -#if BOUT_USE_FCI_AUTOMAGIC - if (rhs.isFci() and rhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < rhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs + rhs.yup(i); - result.ydown(i) = lhs + rhs.ydown(i); - } - } -#endif BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs + rhs[index]; @@ -2296,15 +2106,6 @@ Field3D operator-(const BoutReal lhs, const Field3D& rhs) { checkData(rhs); result.setRegion(rhs.getRegionID()); -#if BOUT_USE_FCI_AUTOMAGIC - if (rhs.isFci() and rhs.hasParallelSlices()) { - result.splitParallelSlices(); - for (size_t i{0}; i < rhs.numberParallelSlices(); ++i) { - result.yup(i) = lhs - rhs.yup(i); - result.ydown(i) = lhs - rhs.ydown(i); - } - } -#endif BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { result[index] = lhs - rhs[index]; @@ -2460,3 +2261,1016 @@ FieldPerp operator-(const BoutReal lhs, const FieldPerp& rhs) { checkData(result); return result; } + +// Provide the C++ wrapper for multiplication of Field3D and Field3DParallel +Field3DParallel operator*(const Field3D& lhs, const Field3DParallel& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(rhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) * rhs.yup(i); + result.ydown(i) = lhs.ydown(i) * rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] * rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} * {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ wrapper for division of Field3D and Field3DParallel +Field3DParallel operator/(const Field3D& lhs, const Field3DParallel& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(rhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) / rhs.yup(i); + result.ydown(i) = lhs.ydown(i) / rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] / rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} / {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ wrapper for addition of Field3D and Field3DParallel +Field3DParallel operator+(const Field3D& lhs, const Field3DParallel& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(rhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) + rhs.yup(i); + result.ydown(i) = lhs.ydown(i) + rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] + rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} + {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ wrapper for subtraction of Field3D and Field3DParallel +Field3DParallel operator-(const Field3D& lhs, const Field3DParallel& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(rhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) - rhs.yup(i); + result.ydown(i) = lhs.ydown(i) - rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] - rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} - {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ wrapper for multiplication of Field3DParallel and Field3D +Field3DParallel operator*(const Field3DParallel& lhs, const Field3D& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) * rhs.yup(i); + result.ydown(i) = lhs.ydown(i) * rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] * rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} * {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by multiplication with Field3D +Field3DParallel& Field3DParallel::operator*=(const Field3D& rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + ASSERT1_FIELDS_COMPATIBLE(*this, rhs); + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) *= rhs.yup(i); + ydown(i) *= rhs.ydown(i); + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] *= rhs[index]; } + + track(rhs, "operator*="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} *= {:s}", this->name, rhs.name); +#endif + + checkData(*this); + + } else { + track(rhs, "operator*="); + (*this) = (*this) * rhs; + } + return *this; +} + +// Provide the C++ wrapper for division of Field3DParallel and Field3D +Field3DParallel operator/(const Field3DParallel& lhs, const Field3D& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) / rhs.yup(i); + result.ydown(i) = lhs.ydown(i) / rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] / rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} / {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by division with Field3D +Field3DParallel& Field3DParallel::operator/=(const Field3D& rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + ASSERT1_FIELDS_COMPATIBLE(*this, rhs); + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) /= rhs.yup(i); + ydown(i) /= rhs.ydown(i); + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] /= rhs[index]; } + + track(rhs, "operator/="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} /= {:s}", this->name, rhs.name); +#endif + + checkData(*this); + + } else { + track(rhs, "operator/="); + (*this) = (*this) / rhs; + } + return *this; +} + +// Provide the C++ wrapper for addition of Field3DParallel and Field3D +Field3DParallel operator+(const Field3DParallel& lhs, const Field3D& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) + rhs.yup(i); + result.ydown(i) = lhs.ydown(i) + rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] + rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} + {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by addition with Field3D +Field3DParallel& Field3DParallel::operator+=(const Field3D& rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + ASSERT1_FIELDS_COMPATIBLE(*this, rhs); + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) += rhs.yup(i); + ydown(i) += rhs.ydown(i); + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] += rhs[index]; } + + track(rhs, "operator+="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} += {:s}", this->name, rhs.name); +#endif + + checkData(*this); + + } else { + track(rhs, "operator+="); + (*this) = (*this) + rhs; + } + return *this; +} + +// Provide the C++ wrapper for subtraction of Field3DParallel and Field3D +Field3DParallel operator-(const Field3DParallel& lhs, const Field3D& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) - rhs.yup(i); + result.ydown(i) = lhs.ydown(i) - rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] - rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} - {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by subtraction with Field3D +Field3DParallel& Field3DParallel::operator-=(const Field3D& rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + ASSERT1_FIELDS_COMPATIBLE(*this, rhs); + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) -= rhs.yup(i); + ydown(i) -= rhs.ydown(i); + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] -= rhs[index]; } + + track(rhs, "operator-="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} -= {:s}", this->name, rhs.name); +#endif + + checkData(*this); + + } else { + track(rhs, "operator-="); + (*this) = (*this) - rhs; + } + return *this; +} + +// Provide the C++ wrapper for multiplication of Field3DParallel and Field3DParallel +Field3DParallel operator*(const Field3DParallel& lhs, const Field3DParallel& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) * rhs.yup(i); + result.ydown(i) = lhs.ydown(i) * rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] * rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} * {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by multiplication with Field3DParallel +Field3DParallel& Field3DParallel::operator*=(const Field3DParallel& rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + ASSERT1_FIELDS_COMPATIBLE(*this, rhs); + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) *= rhs; + ydown(i) *= rhs; + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] *= rhs[index]; } + + track(rhs, "operator*="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} *= {:s}", this->name, rhs.name); +#endif + + checkData(*this); + + } else { + track(rhs, "operator*="); + (*this) = (*this) * rhs; + } + return *this; +} + +// Provide the C++ wrapper for division of Field3DParallel and Field3DParallel +Field3DParallel operator/(const Field3DParallel& lhs, const Field3DParallel& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) / rhs.yup(i); + result.ydown(i) = lhs.ydown(i) / rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] / rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} / {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by division with Field3DParallel +Field3DParallel& Field3DParallel::operator/=(const Field3DParallel& rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + ASSERT1_FIELDS_COMPATIBLE(*this, rhs); + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) /= rhs; + ydown(i) /= rhs; + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] /= rhs[index]; } + + track(rhs, "operator/="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} /= {:s}", this->name, rhs.name); +#endif + + checkData(*this); + + } else { + track(rhs, "operator/="); + (*this) = (*this) / rhs; + } + return *this; +} + +// Provide the C++ wrapper for addition of Field3DParallel and Field3DParallel +Field3DParallel operator+(const Field3DParallel& lhs, const Field3DParallel& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) + rhs.yup(i); + result.ydown(i) = lhs.ydown(i) + rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] + rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} + {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by addition with Field3DParallel +Field3DParallel& Field3DParallel::operator+=(const Field3DParallel& rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + ASSERT1_FIELDS_COMPATIBLE(*this, rhs); + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) += rhs; + ydown(i) += rhs; + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] += rhs[index]; } + + track(rhs, "operator+="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} += {:s}", this->name, rhs.name); +#endif + + checkData(*this); + + } else { + track(rhs, "operator+="); + (*this) = (*this) + rhs; + } + return *this; +} + +// Provide the C++ wrapper for subtraction of Field3DParallel and Field3DParallel +Field3DParallel operator-(const Field3DParallel& lhs, const Field3DParallel& rhs) { + ASSERT1_FIELDS_COMPATIBLE(lhs, rhs); + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getMesh()->getCommonRegion(lhs.getRegionID(), rhs.getRegionID())); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) - rhs.yup(i); + result.ydown(i) = lhs.ydown(i) - rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] - rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} - {:s}", lhs.name, rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by subtraction with Field3DParallel +Field3DParallel& Field3DParallel::operator-=(const Field3DParallel& rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + ASSERT1_FIELDS_COMPATIBLE(*this, rhs); + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) -= rhs; + ydown(i) -= rhs; + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + regionID = fieldmesh->getCommonRegion(regionID, rhs.getRegionID()); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] -= rhs[index]; } + + track(rhs, "operator-="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} -= {:s}", this->name, rhs.name); +#endif + + checkData(*this); + + } else { + track(rhs, "operator-="); + (*this) = (*this) - rhs; + } + return *this; +} + +// Provide the C++ wrapper for multiplication of Field3DParallel and BoutReal +Field3DParallel operator*(const Field3DParallel& lhs, const BoutReal rhs) { + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getRegionID()); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) * rhs; + result.ydown(i) = lhs.ydown(i) * rhs; + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] * rhs; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} * {:s}", lhs.name, "BR"); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by multiplication with BoutReal +Field3DParallel& Field3DParallel::operator*=(const BoutReal rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) *= rhs; + ydown(i) *= rhs; + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] *= rhs; } + + track(rhs, "operator*="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} *= {:s}", this->name, "BR"); +#endif + + checkData(*this); + + } else { + track(rhs, "operator*="); + (*this) = (*this) * rhs; + } + return *this; +} + +// Provide the C++ wrapper for division of Field3DParallel and BoutReal +Field3DParallel operator/(const Field3DParallel& lhs, const BoutReal rhs) { + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getRegionID()); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) / rhs; + result.ydown(i) = lhs.ydown(i) / rhs; + } + } + + const auto tmp = 1.0 / rhs; + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] * tmp; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} / {:s}", lhs.name, "BR"); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by division with BoutReal +Field3DParallel& Field3DParallel::operator/=(const BoutReal rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) /= rhs; + ydown(i) /= rhs; + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] /= rhs; } + + track(rhs, "operator/="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} /= {:s}", this->name, "BR"); +#endif + + checkData(*this); + + } else { + track(rhs, "operator/="); + (*this) = (*this) / rhs; + } + return *this; +} + +// Provide the C++ wrapper for addition of Field3DParallel and BoutReal +Field3DParallel operator+(const Field3DParallel& lhs, const BoutReal rhs) { + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getRegionID()); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) + rhs; + result.ydown(i) = lhs.ydown(i) + rhs; + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] + rhs; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} + {:s}", lhs.name, "BR"); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by addition with BoutReal +Field3DParallel& Field3DParallel::operator+=(const BoutReal rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) += rhs; + ydown(i) += rhs; + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] += rhs; } + + track(rhs, "operator+="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} += {:s}", this->name, "BR"); +#endif + + checkData(*this); + + } else { + track(rhs, "operator+="); + (*this) = (*this) + rhs; + } + return *this; +} + +// Provide the C++ wrapper for subtraction of Field3DParallel and BoutReal +Field3DParallel operator-(const Field3DParallel& lhs, const BoutReal rhs) { + + Field3DParallel result{emptyFrom(lhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(lhs.getRegionID()); + if (result.isFci()) { + result.splitParallelSlices(); + ASSERT2(lhs.hasParallelSlices()); + + for (size_t i{0}; i < lhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs.yup(i) - rhs; + result.ydown(i) = lhs.ydown(i) - rhs; + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs[index] - rhs; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} - {:s}", lhs.name, "BR"); +#endif + checkData(result); + return result; +} + +// Provide the C++ operator to update Field3DParallel by subtraction with BoutReal +Field3DParallel& Field3DParallel::operator-=(const BoutReal rhs) { + // only if data is unique we update the field + // otherwise just call the non-inplace version + if (data.unique()) { + + if (this->isFci()) { + for (size_t i{0}; i < yup_fields.size(); ++i) { + yup(i) -= rhs; + ydown(i) -= rhs; + } + } else { + clearParallelSlices(); + } + checkData(*this); + checkData(rhs); + + BOUT_FOR(index, this->getRegion("RGN_ALL")) { (*this)[index] -= rhs; } + + track(rhs, "operator-="); +#if BOUT_USE_TRACK + name = fmt::format("{:s} -= {:s}", this->name, "BR"); +#endif + + checkData(*this); + + } else { + track(rhs, "operator-="); + (*this) = (*this) - rhs; + } + return *this; +} + +// Provide the C++ wrapper for multiplication of BoutReal and Field3DParallel +Field3DParallel operator*(const BoutReal lhs, const Field3DParallel& rhs) { + + Field3DParallel result{emptyFrom(rhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(rhs.getRegionID()); + if (result.isFci()) { + result.splitParallelSlices(); + + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < rhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs * rhs.yup(i); + result.ydown(i) = lhs * rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs * rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} * {:s}", "BR", rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ wrapper for division of BoutReal and Field3DParallel +Field3DParallel operator/(const BoutReal lhs, const Field3DParallel& rhs) { + + Field3DParallel result{emptyFrom(rhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(rhs.getRegionID()); + if (result.isFci()) { + result.splitParallelSlices(); + + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < rhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs / rhs.yup(i); + result.ydown(i) = lhs / rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs / rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} / {:s}", "BR", rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ wrapper for addition of BoutReal and Field3DParallel +Field3DParallel operator+(const BoutReal lhs, const Field3DParallel& rhs) { + + Field3DParallel result{emptyFrom(rhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(rhs.getRegionID()); + if (result.isFci()) { + result.splitParallelSlices(); + + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < rhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs + rhs.yup(i); + result.ydown(i) = lhs + rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs + rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} + {:s}", "BR", rhs.name); +#endif + checkData(result); + return result; +} + +// Provide the C++ wrapper for subtraction of BoutReal and Field3DParallel +Field3DParallel operator-(const BoutReal lhs, const Field3DParallel& rhs) { + + Field3DParallel result{emptyFrom(rhs)}; + checkData(lhs); + checkData(rhs); + + result.setRegion(rhs.getRegionID()); + if (result.isFci()) { + result.splitParallelSlices(); + + ASSERT2(rhs.hasParallelSlices()); + for (size_t i{0}; i < rhs.numberParallelSlices(); ++i) { + result.yup(i) = lhs - rhs.yup(i); + result.ydown(i) = lhs - rhs.ydown(i); + } + } + + BOUT_FOR(index, result.getValidRegionWithDefault("RGN_ALL")) { + result[index] = lhs - rhs[index]; + } + +#if BOUT_USE_TRACK + result.name = fmt::format("{:s} - {:s}", "BR", rhs.name); +#endif + checkData(result); + return result; +} diff --git a/src/invert/laplacexy2/laplacexy2_hypre.cxx b/src/invert/laplacexy/impls/hypre/laplacexy-hypre.cxx similarity index 95% rename from src/invert/laplacexy2/laplacexy2_hypre.cxx rename to src/invert/laplacexy/impls/hypre/laplacexy-hypre.cxx index a5028169f8..9323513f21 100644 --- a/src/invert/laplacexy2/laplacexy2_hypre.cxx +++ b/src/invert/laplacexy/impls/hypre/laplacexy-hypre.cxx @@ -1,15 +1,26 @@ -#include +#include "bout/build_defines.hxx" #if BOUT_HAS_HYPRE +#include "laplacexy-hypre.hxx" + #include "bout/assert.hxx" +#include "bout/bout_types.hxx" #include "bout/boutcomm.hxx" +#include "bout/coordinates.hxx" +#include "bout/field2d.hxx" +#include "bout/globalindexer.hxx" #include "bout/globals.hxx" #include "bout/mesh.hxx" +#include "bout/operatorstencil.hxx" +#include "bout/options.hxx" #include "bout/output.hxx" +#include "bout/region.hxx" +#include "bout/sys/range.hxx" #include "bout/sys/timer.hxx" -#include +#include +#include #if BOUT_HAS_CUDA && defined(__CUDACC__) #define gpuErrchk(ans) \ @@ -226,7 +237,7 @@ void LaplaceXY2Hypre::setCoefs(const Field2D& A, const Field2D& B) { } } -Field2D LaplaceXY2Hypre::solve(Field2D& rhs, Field2D& x0) { +Field2D LaplaceXY2Hypre::solve(const Field2D& rhs, const Field2D& x0) { Timer timer("invert"); ASSERT1(rhs.getMesh() == localmesh); diff --git a/include/bout/invert/laplacexy2_hypre.hxx b/src/invert/laplacexy/impls/hypre/laplacexy-hypre.hxx similarity index 71% rename from include/bout/invert/laplacexy2_hypre.hxx rename to src/invert/laplacexy/impls/hypre/laplacexy-hypre.hxx index 1df0988d06..f415f9ebf4 100644 --- a/include/bout/invert/laplacexy2_hypre.hxx +++ b/src/invert/laplacexy/impls/hypre/laplacexy-hypre.hxx @@ -33,51 +33,39 @@ #ifndef LAPLACE_XY2_HYPRE_H #define LAPLACE_XY2_HYPRE_H -#include +#include "bout/build_defines.hxx" +#include "bout/invert/laplacexy.hxx" -#if not BOUT_HAS_HYPRE -// If no Hypre +#if !BOUT_HAS_HYPRE -#include "bout/globalindexer.hxx" -#include -#include -#include - -/*! - * Create a dummy class so that code will compile - * without Hypre, but will throw an exception if - * LaplaceXY is used. - */ -class LaplaceXY2Hypre { -public: - LaplaceXY2Hypre(Mesh* UNUSED(m) = nullptr, Options* UNUSED(opt) = nullptr, - const CELL_LOC UNUSED(loc) = CELL_CENTRE) { - throw BoutException("LaplaceXY requires Hypre. No LaplaceXY available"); - } - void setCoefs(const Field2D& UNUSED(A), const Field2D& UNUSED(B)) {} - Field2D solve(const Field2D& UNUSED(rhs), const Field2D& UNUSED(x0)) { - throw BoutException("LaplaceXY requires Hypre. No LaplaceXY available"); - } -}; +namespace { +RegisterUnavailableLaplaceXY + registerlaplacexyhypre("hypre", "BOUT++ was not configured with HYPRE"); +} #else // BOUT_HAS_HYPRE class Mesh; -#include "bout/utils.hxx" -#include +#include "bout/bout_types.hxx" +#include "bout/field2d.hxx" +#include "bout/globalindexer.hxx" +#include "bout/hypre_interface.hxx" -class LaplaceXY2Hypre { +class LaplaceXY2Hypre : public LaplaceXY { public: - LaplaceXY2Hypre(Mesh* m = nullptr, Options* opt = nullptr, - const CELL_LOC loc = CELL_CENTRE); - ~LaplaceXY2Hypre() = default; + LaplaceXY2Hypre(Mesh* m = nullptr, Options* opt = nullptr, CELL_LOC loc = CELL_CENTRE); + LaplaceXY2Hypre(const LaplaceXY2Hypre&) = delete; + LaplaceXY2Hypre(LaplaceXY2Hypre&&) = delete; + LaplaceXY2Hypre& operator=(const LaplaceXY2Hypre&) = delete; + LaplaceXY2Hypre& operator=(LaplaceXY2Hypre&&) = delete; + ~LaplaceXY2Hypre() override = default; /*! * Set coefficients (A, B) in equation: * Div( A * Grad_perp(x) ) + B*x = b */ - void setCoefs(const Field2D& A, const Field2D& B); + void setCoefs(const Field2D& A, const Field2D& B) override; /*! * Solve Laplacian in X-Y @@ -96,7 +84,7 @@ public: * The solution as a Field2D. On failure an exception will be raised * */ - Field2D solve(Field2D& rhs, Field2D& x0); + Field2D solve(const Field2D& rhs, const Field2D& x0) override; /*! * Preconditioner function @@ -131,5 +119,9 @@ private: MPI_Comm communicator(); }; +namespace { +const inline RegisterLaplaceXY registerlaplacexyhypre{"hypre"}; +} + #endif // BOUT_HAS_HYPRE #endif // LAPLACE_XY_HYPRE_H diff --git a/src/invert/laplacexy/impls/petsc/laplacexy-petsc.cxx b/src/invert/laplacexy/impls/petsc/laplacexy-petsc.cxx new file mode 100644 index 0000000000..04abecfe05 --- /dev/null +++ b/src/invert/laplacexy/impls/petsc/laplacexy-petsc.cxx @@ -0,0 +1,1899 @@ +#include "bout/build_defines.hxx" + +#if BOUT_HAS_PETSC + +#include "laplacexy-petsc.hxx" + +#include "bout/assert.hxx" +#include "bout/bout_types.hxx" +#include "bout/boutcomm.hxx" +#include "bout/boutexception.hxx" +#include "bout/cyclic_reduction.hxx" +#include "bout/derivs.hxx" +#include "bout/field2d.hxx" +#include "bout/globals.hxx" +#include "bout/options.hxx" +#include "bout/petsclib.hxx" +#include "bout/solver.hxx" +#include "bout/sys/range.hxx" +#include "bout/sys/timer.hxx" +#include "bout/utils.hxx" + +#include +#include + +#include + +namespace { +PetscErrorCode laplacePCapply(PC pc, Vec x, Vec y) { + // Get the context + LaplaceXYpetsc* s = nullptr; + const auto ierr = PCShellGetContext(pc, reinterpret_cast(&s)); + CHKERRQ(ierr); + + PetscFunctionReturn(s->precon(x, y)); +} +} // namespace + +LaplaceXYpetsc::LaplaceXYpetsc(Mesh* m, Options* opt, const CELL_LOC loc) + : lib(opt == nullptr ? &(Options::root()["laplacexy"]) : opt), + localmesh(m == nullptr ? bout::globals::mesh : m), location(loc), monitor(*this) { + Timer timer("invert"); + + if (opt == nullptr) { + // If no options supplied, use default + opt = &(Options::root()["laplacexy"]); + } + + finite_volume = + (*opt)["finite_volume"] + .doc("Use finite volume rather than finite difference discretisation.") + .withDefault(true); + + /////////////////////////////////////////////////// + // Boundary condititions options + if (localmesh->periodicY(localmesh->xstart)) { + // Periodic in Y, so in the core + x_inner_dirichlet = (*opt)["core_bndry_dirichlet"].withDefault(false); + } else { + // Non-periodic, so in the PF region + x_inner_dirichlet = (*opt)["pf_bndry_dirichlet"].withDefault(true); + } + if ((*opt)["y_bndry_dirichlet"].isSet()) { + throw BoutException("y_bndry_dirichlet has been deprecated. Use y_bndry=dirichlet " + "instead."); + } + y_bndry = (*opt)["y_bndry"].withDefault("neumann"); + + // Check value of y_bndry is a supported option + if (not(y_bndry == "dirichlet" or y_bndry == "neumann" or y_bndry == "free_o3")) { + + throw BoutException("Unrecognized option '{}' for laplacexy:ybndry", y_bndry); + } + + if (not finite_volume) { + // Check we can use corner cells + if (not localmesh->include_corner_cells) { + throw BoutException( + "Finite difference form of LaplaceXYpetsc allows non-orthogonal x- and " + "y-directions, so requires mesh:include_corner_cells=true."); + } + } + + // Use name of options section as the default prefix for performance logging variables + default_prefix = opt->name(); + + // Get MPI communicator + auto comm = BoutComm::get(); + + // Local size + const int localN = localSize(); + + // Create Vectors + VecCreate(comm, &xs); + VecSetSizes(xs, localN, PETSC_DETERMINE); + VecSetFromOptions(xs); + VecDuplicate(xs, &bs); + + // Set size of Matrix on each processor to localN x localN + MatCreate(comm, &MatA); + MatSetSizes(MatA, localN, localN, PETSC_DETERMINE, PETSC_DETERMINE); + MatSetFromOptions(MatA); + + ////////////////////////////////////////////////// + // Specify local indices. This creates a mapping + // from local indices to index, using a Field2D object + + indexXY = -1; // Set all points to -1, indicating out of domain + + int ind = 0; + + // Y boundaries + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + indexXY(it.ind, localmesh->ystart - 1) = ind++; + } + if ((not finite_volume) and localmesh->hasBndryLowerY()) { + // Corner boundary cells + if (localmesh->firstX()) { + indexXY(localmesh->xstart - 1, localmesh->ystart - 1) = ind++; + } + if (localmesh->lastX()) { + indexXY(localmesh->xend + 1, localmesh->ystart - 1) = ind++; + } + } + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + indexXY(it.ind, localmesh->yend + 1) = ind++; + } + if ((not finite_volume) and localmesh->hasBndryUpperY()) { + // Corner boundary cells + if (localmesh->firstX()) { + indexXY(localmesh->xstart - 1, localmesh->yend + 1) = ind++; + } + if (localmesh->lastX()) { + indexXY(localmesh->xend + 1, localmesh->yend + 1) = ind++; + } + } + + xstart = localmesh->xstart; + if (localmesh->firstX()) { + xstart -= 1; // Include X guard cells + } + xend = localmesh->xend; + if (localmesh->lastX()) { + xend += 1; + } + for (int x = xstart; x <= xend; x++) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + indexXY(x, y) = ind++; + } + } + + ASSERT1(ind == localN); // Reached end of range + + ////////////////////////////////////////////////// + // Allocate storage for preconditioner + + nloc = xend - xstart + 1; // Number of X points on this processor + nsys = localmesh->yend - localmesh->ystart + 1; // Number of separate Y slices + + acoef.reallocate(nsys, nloc); + bcoef.reallocate(nsys, nloc); + ccoef.reallocate(nsys, nloc); + xvals.reallocate(nsys, nloc); + bvals.reallocate(nsys, nloc); + + // Create a cyclic reduction object + cr = bout::utils::make_unique>(localmesh->getXcomm(), nloc); + + ////////////////////////////////////////////////// + // Pre-allocate PETSc storage + + PetscInt* d_nnz = nullptr; + PetscInt* o_nnz = nullptr; + PetscMalloc((localN) * sizeof(PetscInt), &d_nnz); + PetscMalloc((localN) * sizeof(PetscInt), &o_nnz); + + if (finite_volume) { + setPreallocationFiniteVolume(d_nnz, o_nnz); + } else { + setPreallocationFiniteDifference(d_nnz, o_nnz); + } + // Pre-allocate + MatMPIAIJSetPreallocation(MatA, 0, d_nnz, 0, o_nnz); + MatSetUp(MatA); + + PetscFree(d_nnz); + PetscFree(o_nnz); + + // Determine which row/columns of the matrix are locally owned + int Istart = 0; + int Iend = 0; + MatGetOwnershipRange(MatA, &Istart, &Iend); + + // Convert indexXY from local index to global index + indexXY += Istart; + + // Now communicate to fill guard cells + // Note, this includes corner cells if necessary + localmesh->communicate(indexXY); + + ////////////////////////////////////////////////// + // Set up KSP + + // Declare KSP Context + KSPCreate(comm, &ksp); + + // Configure Linear Solver + + const bool direct = (*opt)["direct"].doc("Use a direct LU solver").withDefault(false); + + if (direct) { + KSPGetPC(ksp, &pc); + PCSetType(pc, PCLU); +#if PETSC_VERSION_GE(3, 9, 0) + PCFactorSetMatSolverType(pc, "mumps"); +#else + PCFactorSetMatSolverPackage(pc, "mumps"); +#endif + } else { + + // Convergence Parameters. Solution is considered converged if |r_k| < max( rtol * |b| , atol ) + // where r_k = b - Ax_k. The solution is considered diverged if |r_k| > dtol * |b|. + + const BoutReal rtol = (*opt)["rtol"].doc("Relative tolerance").withDefault(1e-5); + const BoutReal atol = + (*opt)["atol"] + .doc("Absolute tolerance. The solution is considered converged if |Ax-b| " + "< max( rtol * |b| , atol )") + .withDefault(1e-10); + const BoutReal dtol = + (*opt)["dtol"] + .doc("The solution is considered diverged if |Ax-b| > dtol * |b|") + .withDefault(1e3); + const int maxits = (*opt)["maxits"].doc("Maximum iterations").withDefault(100000); + + // Get KSP Solver Type + const std::string ksptype = + (*opt)["ksptype"].doc("KSP solver type").withDefault("gmres"); + + // Get PC type + const std::string pctype = + (*opt)["pctype"].doc("Preconditioner type").withDefault("none"); + + KSPSetType(ksp, ksptype.c_str()); + KSPSetTolerances(ksp, rtol, atol, dtol, maxits); + + KSPSetInitialGuessNonzero(ksp, static_cast(true)); + + KSPGetPC(ksp, &pc); + PCSetType(pc, pctype.c_str()); + + if (pctype == "shell") { + // Using tridiagonal solver as preconditioner + PCShellSetApply(pc, laplacePCapply); + PCShellSetContext(pc, this); + + const bool rightprec = + (*opt)["rightprec"].doc("Use right preconditioning?").withDefault(true); + if (rightprec) { + KSPSetPCSide(ksp, PC_RIGHT); // Right preconditioning + } else { + KSPSetPCSide(ksp, PC_LEFT); // Left preconditioning + } + } + } + + lib.setOptionsFromInputFile(ksp); + + /////////////////////////////////////////////////// + // Including Y derivatives? + + include_y_derivs = (*opt)["include_y_derivs"] + .doc("Include Y derivatives in operator to invert?") + .withDefault(true); + + /////////////////////////////////////////////////// + // Set the default coefficients + Field2D one(1., localmesh); + Field2D zero(0., localmesh); + one.setLocation(location); + zero.setLocation(location); + setCoefs(one, zero); +} + +void LaplaceXYpetsc::setPreallocationFiniteVolume(PetscInt* d_nnz, PetscInt* o_nnz) { + const int localN = localSize(); + + // This discretisation uses a 5-point stencil + for (int i = 0; i < localN; i++) { + // Non-zero elements on this processor + d_nnz[i] = 5; // Star pattern in 2D + // Non-zero elements on neighboring processor + o_nnz[i] = 0; + } + + // X boundaries + if (localmesh->firstX()) { + // Lower X boundary + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + const int localIndex = globalIndex(localmesh->xstart - 1, y); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + + d_nnz[localIndex] = 2; // Diagonal sub-matrix + o_nnz[localIndex] = 0; // Off-diagonal sub-matrix + } + } else { + // On another processor + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + const int localIndex = globalIndex(localmesh->xstart, y); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] -= 1; + o_nnz[localIndex] += 1; + } + } + if (localmesh->lastX()) { + // Upper X boundary + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + const int localIndex = globalIndex(localmesh->xend + 1, y); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = 2; // Diagonal sub-matrix + o_nnz[localIndex] = 0; // Off-diagonal sub-matrix + } + } else { + // On another processor + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + const int localIndex = globalIndex(localmesh->xend, y); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] -= 1; + o_nnz[localIndex] += 1; + } + } + // Y boundaries + + for (int x = localmesh->xstart; x <= localmesh->xend; x++) { + // Default to no boundary + // NOTE: This assumes that communications in Y are to other + // processors. If Y is communicated with this processor (e.g. NYPE=1) + // then this will result in PETSc warnings about out of range allocations + { + const int localIndex = globalIndex(x, localmesh->ystart); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + // d_nnz[localIndex] -= 1; // Note: Slightly inefficient + o_nnz[localIndex] += 1; + } + { + const int localIndex = globalIndex(x, localmesh->yend); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + // d_nnz[localIndex] -= 1; // Note: Slightly inefficient + o_nnz[localIndex] += 1; + } + } + + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + { + const int localIndex = globalIndex(it.ind, localmesh->ystart - 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = 2; // Diagonal sub-matrix + o_nnz[localIndex] = 0; // Off-diagonal sub-matrix + } + { + const int localIndex = globalIndex(it.ind, localmesh->ystart); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] += 1; + o_nnz[localIndex] -= 1; + } + } + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + { + const int localIndex = globalIndex(it.ind, localmesh->yend + 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = 2; // Diagonal sub-matrix + o_nnz[localIndex] = 0; // Off-diagonal sub-matrix + } + { + const int localIndex = globalIndex(it.ind, localmesh->yend); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] += 1; + o_nnz[localIndex] -= 1; + } + } +} + +void LaplaceXYpetsc::setPreallocationFiniteDifference(PetscInt* d_nnz, PetscInt* o_nnz) { + const int localN = localSize(); + + // This discretisation uses a 9-point stencil + for (int i = 0; i < localN; i++) { + // Non-zero elements on this processor + d_nnz[i] = 9; // Square pattern in 2D + // Non-zero elements on neighboring processor + o_nnz[i] = 0; + } + + // X boundaries + if (localmesh->firstX()) { + // Lower X boundary + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + const int localIndex = globalIndex(localmesh->xstart - 1, y); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + + d_nnz[localIndex] = 2; // Diagonal sub-matrix + o_nnz[localIndex] = 0; // Off-diagonal sub-matrix + } + } else { + // On another processor + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + const int localIndex = globalIndex(localmesh->xstart, y); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] -= 3; + o_nnz[localIndex] += 3; + } + } + if (localmesh->lastX()) { + // Upper X boundary + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + const int localIndex = globalIndex(localmesh->xend + 1, y); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = 2; // Diagonal sub-matrix + o_nnz[localIndex] = 0; // Off-diagonal sub-matrix + } + } else { + // On another processor + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + const int localIndex = globalIndex(localmesh->xend, y); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] -= 3; + o_nnz[localIndex] += 3; + } + } + // Y boundaries + const int y_bndry_stencil_size = (y_bndry == "free_o3") ? 4 : 2; + + for (int x = localmesh->xstart; x <= localmesh->xend; x++) { + // Default to no boundary + // NOTE: This assumes that communications in Y are to other + // processors. If Y is communicated with this processor (e.g. NYPE=1) + // then this will result in PETSc warnings about out of range allocations + { + const int localIndex = globalIndex(x, localmesh->ystart); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + // d_nnz[localIndex] -= 3; // Note: Slightly inefficient + o_nnz[localIndex] += 3; + } + { + const int localIndex = globalIndex(x, localmesh->yend); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + // d_nnz[localIndex] -= 3; // Note: Slightly inefficient + o_nnz[localIndex] += 3; + } + } + + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, they are handled specially below + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + { + const int localIndex = globalIndex(it.ind, localmesh->ystart - 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = y_bndry_stencil_size; // Diagonal sub-matrix + o_nnz[localIndex] = 0; // Off-diagonal sub-matrix + } + { + const int localIndex = globalIndex(it.ind, localmesh->ystart); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + //d_nnz[localIndex] += 3; + o_nnz[localIndex] -= 3; + } + } + if (localmesh->hasBndryLowerY()) { + if (y_bndry == "dirichlet") { + // special handling for the corners, since we use a free_o3 y-boundary + // condition just in the corners when y_bndry=="dirichlet" + if (localmesh->firstX()) { + const int localIndex = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = 4; + } + if (localmesh->lastX()) { + const int localIndex = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = 4; + } + } else { + if (localmesh->firstX()) { + const int localIndex = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = y_bndry_stencil_size; + } + if (localmesh->lastX()) { + const int localIndex = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = y_bndry_stencil_size; + } + } + } + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, they are handled specially below + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + { + const int localIndex = globalIndex(it.ind, localmesh->yend + 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = y_bndry_stencil_size; // Diagonal sub-matrix + o_nnz[localIndex] = 0; // Off-diagonal sub-matrix + } + { + const int localIndex = globalIndex(it.ind, localmesh->yend); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + //d_nnz[localIndex] += 3; + o_nnz[localIndex] -= 3; + } + } + if (localmesh->hasBndryUpperY()) { + if (y_bndry == "dirichlet") { + // special handling for the corners, since we use a free_o3 y-boundary + // condition just in the corners when y_bndry=="dirichlet" + if (localmesh->firstX()) { + const int localIndex = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = 4; + } + if (localmesh->lastX()) { + const int localIndex = globalIndex(localmesh->xend + 1, localmesh->yend + 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = 4; + } + } else { + if (localmesh->firstX()) { + const int localIndex = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = y_bndry_stencil_size; + } + if (localmesh->lastX()) { + const int localIndex = globalIndex(localmesh->xend + 1, localmesh->yend + 1); + ASSERT1((localIndex >= 0) && (localIndex < localN)); + d_nnz[localIndex] = y_bndry_stencil_size; + } + } + } +} + +void LaplaceXYpetsc::setCoefs(const Field2D& A, const Field2D& B) { + Timer timer("invert"); + + ASSERT1(A.getMesh() == localmesh); + ASSERT1(B.getMesh() == localmesh); + ASSERT1(A.getLocation() == location); + ASSERT1(B.getLocation() == location); + + if (finite_volume) { + setMatrixElementsFiniteVolume(A, B); + } else { + setMatrixElementsFiniteDifference(A, B); + } + + // X boundaries + if (localmesh->firstX()) { + if (x_inner_dirichlet) { + + // Dirichlet on inner X boundary + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int row = globalIndex(localmesh->xstart - 1, y); + PetscScalar val = 0.5; + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + int col = globalIndex(localmesh->xstart, y); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + // Preconditioner + bcoef(y - localmesh->ystart, 0) = 0.5; + ccoef(y - localmesh->ystart, 0) = 0.5; + } + + } else { + + // Neumann on inner X boundary + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int row = globalIndex(localmesh->xstart - 1, y); + PetscScalar val = 1.0; + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + int col = globalIndex(localmesh->xstart, y); + val = -1.0; + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + // Preconditioner + bcoef(y - localmesh->ystart, 0) = 1.0; + ccoef(y - localmesh->ystart, 0) = -1.0; + } + } + } + if (localmesh->lastX()) { + // Dirichlet on outer X boundary + + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int row = globalIndex(localmesh->xend + 1, y); + PetscScalar val = 0.5; + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + int col = globalIndex(localmesh->xend, y); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + // Preconditioner + acoef(y - localmesh->ystart, localmesh->xend + 1 - xstart) = 0.5; + bcoef(y - localmesh->ystart, localmesh->xend + 1 - xstart) = 0.5; + } + } + + if (y_bndry == "dirichlet") { + // Dirichlet on Y boundaries + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int row = globalIndex(it.ind, localmesh->ystart - 1); + PetscScalar val = 0.5; + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + int col = globalIndex(it.ind, localmesh->ystart); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } + + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int row = globalIndex(it.ind, localmesh->yend + 1); + PetscScalar val = 0.5; + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + int col = globalIndex(it.ind, localmesh->yend); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } + } else if (y_bndry == "neumann") { + // Neumann on Y boundaries + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int row = globalIndex(it.ind, localmesh->ystart - 1); + PetscScalar val = 1.0; + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -1.0; + int col = globalIndex(it.ind, localmesh->ystart); + + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } + + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int row = globalIndex(it.ind, localmesh->yend + 1); + PetscScalar val = 1.0; + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -1.0; + int col = globalIndex(it.ind, localmesh->yend); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } + } else if (y_bndry == "free_o3") { + // 'free_o3' extrapolating boundary condition on Y boundaries + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int row = globalIndex(it.ind, localmesh->ystart - 1); + PetscScalar val = 1.0; + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -3.0; + int col = globalIndex(it.ind, localmesh->ystart); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = 3.0; + col = globalIndex(it.ind, localmesh->ystart + 1); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = -1.0; + col = globalIndex(it.ind, localmesh->ystart + 2); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } + + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int row = globalIndex(it.ind, localmesh->yend + 1); + PetscScalar val = 1.0; + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -3.0; + int col = globalIndex(it.ind, localmesh->yend); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = 3.0; + col = globalIndex(it.ind, localmesh->yend - 1); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = -1.0; + col = globalIndex(it.ind, localmesh->yend - 2); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } + } else { + throw BoutException("Unsupported option for y_bndry"); + } + + if (not finite_volume) { + // Handle corner boundary cells in case we need to include D2DXDY + // Apply the y-boundary-condition to the cells in the x-boundary - this is an + // arbitrary choice, cf. connections around the X-point + + if (localmesh->hasBndryLowerY()) { + if (localmesh->firstX()) { + if (y_bndry == "neumann") { + // Neumann y-bc + // f(xs-1,ys-1) = f(xs-1,ys) + PetscScalar val = 1.0; + int row = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -1.0; + int col = globalIndex(localmesh->xstart - 1, localmesh->ystart); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } else if (y_bndry == "free_o3" or y_bndry == "dirichlet") { + // 'free_o3' extrapolating boundary condition on Y boundaries + // f(xs-1,ys-1) = 3*f(xs-1,ys) - 3*f(xs-1,ys+1) + f(xs-1,ys+2) + // + // Use free_o3 at the corners for Dirichlet y-boundaries because we don't know + // what value to pass for the corner + PetscScalar val = 1.0; + int row = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -3.0; + int col = globalIndex(localmesh->xstart - 1, localmesh->ystart); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = 3.0; + col = globalIndex(localmesh->xstart - 1, localmesh->ystart + 1); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = -1.0; + col = globalIndex(localmesh->xstart - 1, localmesh->ystart + 2); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } else { + throw BoutException("Unsupported option for y_bndry"); + } + } + if (localmesh->lastX()) { + if (y_bndry == "neumann") { + // Neumann y-bc + // f(xe+1,ys-1) = f(xe+1,ys) + PetscScalar val = 1.0; + int row = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -1.0; + int col = globalIndex(localmesh->xend + 1, localmesh->ystart); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } else if (y_bndry == "free_o3" or y_bndry == "dirichlet") { + // 'free_o3' extrapolating boundary condition on Y boundaries + // f(xe+1,ys-1) = 3*f(xe+1,ys) - 3*f(xe+1,ys+1) + f(xe+1,ys+2) + // + // Use free_o3 at the corners for Dirichlet y-boundaries because we don't know + // what value to pass for the corner + PetscScalar val = 1.0; + int row = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -3.0; + int col = globalIndex(localmesh->xend + 1, localmesh->ystart); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = 3.0; + col = globalIndex(localmesh->xend + 1, localmesh->ystart + 1); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = -1.0; + col = globalIndex(localmesh->xend + 1, localmesh->ystart + 2); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } else { + throw BoutException("Unsupported option for y_bndry"); + } + } + } + if (localmesh->hasBndryUpperY()) { + if (localmesh->firstX()) { + if (y_bndry == "neumann") { + // Neumann y-bc + // f(xs-1,ys-1) = f(xs-1,ys) + PetscScalar val = 1.0; + int row = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -1.0; + int col = globalIndex(localmesh->xstart - 1, localmesh->yend); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } else if (y_bndry == "free_o3" or y_bndry == "dirichlet") { + // 'free_o3' extrapolating boundary condition on Y boundaries + // f(xs-1,ys-1) = 3*f(xs-1,ys) - 3*f(xs-1,ys+1) + f(xs-1,ys+2) + // + // Use free_o3 at the corners for Dirichlet y-boundaries because we don't know + // what value to pass for the corner + PetscScalar val = 1.0; + int row = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -3.0; + int col = globalIndex(localmesh->xstart - 1, localmesh->yend); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = 3.0; + col = globalIndex(localmesh->xstart - 1, localmesh->yend - 1); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = -1.0; + col = globalIndex(localmesh->xstart - 1, localmesh->yend - 2); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } else { + throw BoutException("Unsupported option for y_bndry"); + } + } + if (localmesh->lastX()) { + if (y_bndry == "neumann") { + // Neumann y-bc + // f(xe+1,ys-1) = f(xe+1,ys) + PetscScalar val = 1.0; + int row = globalIndex(localmesh->xend + 1, localmesh->yend + 1); + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -1.0; + int col = globalIndex(localmesh->xend + 1, localmesh->yend); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } else if (y_bndry == "free_o3" or y_bndry == "dirichlet") { + // 'free_o3' extrapolating boundary condition on Y boundaries + // f(xe+1,ys-1) = 3*f(xe+1,ys) - 3*f(xe+1,ys+1) + f(xe+1,ys+2) + // + // Use free_o3 at the corners for Dirichlet y-boundaries because we don't know + // what value to pass for the corner + PetscScalar val = 1.0; + int row = globalIndex(localmesh->xend + 1, localmesh->yend + 1); + MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); + + val = -3.0; + int col = globalIndex(localmesh->xend + 1, localmesh->yend); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = 3.0; + col = globalIndex(localmesh->xend + 1, localmesh->yend - 1); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + + val = -1.0; + col = globalIndex(localmesh->xend + 1, localmesh->yend - 2); + MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); + } else { + throw BoutException("Unsupported option for y_bndry"); + } + } + } + } + + // Assemble Matrix + MatAssemblyBegin(MatA, MAT_FINAL_ASSEMBLY); + MatAssemblyEnd(MatA, MAT_FINAL_ASSEMBLY); + + // Set the operator +#if PETSC_VERSION_GE(3, 5, 0) + KSPSetOperators(ksp, MatA, MatA); +#else + KSPSetOperators(ksp, MatA, MatA, DIFFERENT_NONZERO_PATTERN); +#endif + + // Set coefficients for preconditioner + cr->setCoefs(acoef, bcoef, ccoef); +} + +void LaplaceXYpetsc::setMatrixElementsFiniteVolume(const Field2D& A, const Field2D& B) { + ////////////////////////////////////////////////// + // Set Matrix elements + // + // (1/J) d/dx ( J * g11 d/dx ) + (1/J) d/dy ( J * g22 d/dy ) + + auto coords = localmesh->getCoordinates(location); + const Field2D J_DC = DC(coords->J); + const Field2D g11_DC = DC(coords->g11); + const Field2D dx_DC = DC(coords->dx); + const Field2D dy_DC = DC(coords->dy); + const Field2D g_22_DC = DC(coords->g_22); + const Field2D g_23_DC = DC(coords->g_23); + const Field2D g23_DC = DC(coords->g23); + + for (int x = localmesh->xstart; x <= localmesh->xend; x++) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + // stencil entries + PetscScalar c, xm, xp, ym, yp; + + // XX component + + // Metrics on x+1/2 boundary + BoutReal J = 0.5 * (J_DC(x, y) + J_DC(x + 1, y)); + BoutReal g11 = 0.5 * (g11_DC(x, y) + g11_DC(x + 1, y)); + BoutReal dx = 0.5 * (dx_DC(x, y) + dx_DC(x + 1, y)); + BoutReal Acoef = 0.5 * (A(x, y) + A(x + 1, y)); + + BoutReal val = Acoef * J * g11 / (J_DC(x, y) * dx * dx_DC(x, y)); + xp = val; + c = -val; + + // Metrics on x-1/2 boundary + J = 0.5 * (J_DC(x, y) + J_DC(x - 1, y)); + g11 = 0.5 * (g11_DC(x, y) + g11_DC(x - 1, y)); + dx = 0.5 * (dx_DC(x, y) + dx_DC(x - 1, y)); + Acoef = 0.5 * (A(x, y) + A(x - 1, y)); + + val = Acoef * J * g11 / (J_DC(x, y) * dx * dx_DC(x, y)); + xm = val; + c -= val; + + c += B(x, y); + + // Put values into the preconditioner, X derivatives only + acoef(y - localmesh->ystart, x - xstart) = xm; + bcoef(y - localmesh->ystart, x - xstart) = c; + ccoef(y - localmesh->ystart, x - xstart) = xp; + + if (include_y_derivs) { + // YY component + // Metrics at y+1/2 + J = 0.5 * (J_DC(x, y) + J_DC(x, y + 1)); + BoutReal g_22 = 0.5 * (g_22_DC(x, y) + g_22_DC(x, y + 1)); + BoutReal g23 = 0.5 * (g23_DC(x, y) + g23_DC(x, y + 1)); + BoutReal g_23 = 0.5 * (g_23_DC(x, y) + g_23_DC(x, y + 1)); + BoutReal dy = 0.5 * (dy_DC(x, y) + dy_DC(x, y + 1)); + Acoef = 0.5 * (A(x, y + 1) + A(x, y)); + + val = -Acoef * J * g23 * g_23 / (g_22 * J_DC(x, y) * dy * dy_DC(x, y)); + yp = val; + c -= val; + + // Metrics at y-1/2 + J = 0.5 * (J_DC(x, y) + J_DC(x, y - 1)); + g_22 = 0.5 * (g_22_DC(x, y) + g_22_DC(x, y - 1)); + g23 = 0.5 * (g23_DC(x, y) + g23_DC(x, y - 1)); + g_23 = 0.5 * (g_23_DC(x, y) + g_23_DC(x, y - 1)); + dy = 0.5 * (dy_DC(x, y) + dy_DC(x, y - 1)); + Acoef = 0.5 * (A(x, y - 1) + A(x, y)); + + val = -Acoef * J * g23 * g_23 / (g_22 * J_DC(x, y) * dy * dy_DC(x, y)); + ym = val; + c -= val; + } + + ///////////////////////////////////////////////// + // Now have a 5-point stencil for the Laplacian + + int row = globalIndex(x, y); + + // Set the centre (diagonal) + MatSetValues(MatA, 1, &row, 1, &row, &c, INSERT_VALUES); + + // X + 1 + int col = globalIndex(x + 1, y); + MatSetValues(MatA, 1, &row, 1, &col, &xp, INSERT_VALUES); + + // X - 1 + col = globalIndex(x - 1, y); + MatSetValues(MatA, 1, &row, 1, &col, &xm, INSERT_VALUES); + + if (include_y_derivs) { + // Y + 1 + col = globalIndex(x, y + 1); + MatSetValues(MatA, 1, &row, 1, &col, &yp, INSERT_VALUES); + + // Y - 1 + col = globalIndex(x, y - 1); + MatSetValues(MatA, 1, &row, 1, &col, &ym, INSERT_VALUES); + } + } + } +} + +void LaplaceXYpetsc::setMatrixElementsFiniteDifference(const Field2D& A, + const Field2D& B) { + ////////////////////////////////////////////////// + // Set Matrix elements + // + // Div(A Grad(f)) + B f + // = A Laplace_perp(f) + Grad_perp(A).Grad_perp(f) + B f + // = A*(G1*dfdx + (G2-1/J*d/dy(J/g_22))*dfdy + // + g11*d2fdx2 + (g22-1/g_22)*d2fdy2 + 2*g12*d2fdxdy) + // + g11*dAdx*dfdx + (g22-1/g_22)*dAdy*dfdy + g12*(dAdx*dfdy + dAdy*dfdx) + // + B*f + + auto coords = localmesh->getCoordinates(location); + const Field2D G1_2D = DC(coords->G1); + const Field2D G2_2D = DC(coords->G2); + const Field2D J_2D = DC(coords->J); + const Field2D g11_2D = DC(coords->g11); + const Field2D g_22_2D = DC(coords->g_22); + const Field2D g22_2D = DC(coords->g22); + const Field2D g12_2D = DC(coords->g12); + const Field2D d1_dx_2D = DC(coords->d1_dx); + const Field2D d1_dy_2D = DC(coords->d1_dy); + const Field2D dx_2D = DC(coords->dx); + const Field2D dy_2D = DC(coords->dy); + + const Field2D coef_dfdy = G2_2D - DC(DDY(J_2D / g_22_2D) / J_2D); + + for (int x = localmesh->xstart; x <= localmesh->xend; x++) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + // stencil entries + PetscScalar c, xm, xp, ym, yp, xpyp, xpym, xmyp, xmym; + + BoutReal dx = dx_2D(x, y); + + // A*G1*dfdx + BoutReal val = A(x, y) * G1_2D(x, y) / (2. * dx); + xp = val; + xm = -val; + + // A*g11*d2fdx2 + val = A(x, y) * g11_2D(x, y) / SQ(dx); + xp += val; + c = -2. * val; + xm += val; + // Non-uniform grid correction + val = A(x, y) * g11_2D(x, y) * d1_dx_2D(x, y) / (2. * dx); + xp += val; + xm -= val; + + // g11*dAdx*dfdx + val = g11_2D(x, y) * (A(x + 1, y) - A(x - 1, y)) / (4. * SQ(dx)); + xp += val; + xm -= val; + + // B*f + c += B(x, y); + + // Put values into the preconditioner, X derivatives only + acoef(y - localmesh->ystart, x - xstart) = xm; + bcoef(y - localmesh->ystart, x - xstart) = c; + ccoef(y - localmesh->ystart, x - xstart) = xp; + + if (include_y_derivs) { + BoutReal dy = dy_2D(x, y); + BoutReal dAdx = (A(x + 1, y) - A(x - 1, y)) / (2. * dx); + BoutReal dAdy = (A(x, y + 1) - A(x, y - 1)) / (2. * dy); + + // A*(G2-1/J*d/dy(J/g_22))*dfdy + val = A(x, y) * coef_dfdy(x, y) / (2. * dy); + yp = val; + ym = -val; + + // A*(g22-1/g_22)*d2fdy2 + val = A(x, y) * (g22_2D(x, y) - 1. / g_22_2D(x, y)) / SQ(dy); + yp += val; + c -= 2. * val; + ym += val; + // Non-uniform mesh correction + val = A(x, y) * (g22_2D(x, y) - 1. / g_22_2D(x, y)) * d1_dy_2D(x, y) / (2. * dy); + yp += val; + ym -= val; + + // 2*A*g12*d2dfdxdy + val = A(x, y) * g12_2D(x, y) / (2. * dx * dy); + xpyp = val; + xpym = -val; + xmyp = -val; + xmym = val; + + // g22*dAdy*dfdy + val = (g22_2D(x, y) - 1. / g_22_2D(x, y)) * dAdy / (2. * dy); + yp += val; + ym -= val; + + // g12*(dAdx*dfdy + dAdy*dfdx) + val = g12_2D(x, y) * dAdx / (2. * dy); + yp += val; + ym -= val; + val = g12_2D(x, y) * dAdy / (2. * dx); + xp += val; + xm -= val; + } + + ///////////////////////////////////////////////// + // Now have a 9-point stencil for the Laplacian + + int row = globalIndex(x, y); + + // Set the centre (diagonal) + MatSetValues(MatA, 1, &row, 1, &row, &c, INSERT_VALUES); + + // X + 1 + int col = globalIndex(x + 1, y); + MatSetValues(MatA, 1, &row, 1, &col, &xp, INSERT_VALUES); + + // X - 1 + col = globalIndex(x - 1, y); + MatSetValues(MatA, 1, &row, 1, &col, &xm, INSERT_VALUES); + + if (include_y_derivs) { + // Y + 1 + col = globalIndex(x, y + 1); + MatSetValues(MatA, 1, &row, 1, &col, &yp, INSERT_VALUES); + + // Y - 1 + col = globalIndex(x, y - 1); + MatSetValues(MatA, 1, &row, 1, &col, &ym, INSERT_VALUES); + + // X + 1, Y + 1 + col = globalIndex(x + 1, y + 1); + MatSetValues(MatA, 1, &row, 1, &col, &xpyp, INSERT_VALUES); + + // X + 1, Y - 1 + col = globalIndex(x + 1, y - 1); + MatSetValues(MatA, 1, &row, 1, &col, &xpym, INSERT_VALUES); + + // X - 1, Y + 1 + col = globalIndex(x - 1, y + 1); + MatSetValues(MatA, 1, &row, 1, &col, &xmyp, INSERT_VALUES); + + // X - 1, Y - 1 + col = globalIndex(x - 1, y - 1); + MatSetValues(MatA, 1, &row, 1, &col, &xmym, INSERT_VALUES); + } + } + } +} + +LaplaceXYpetsc::~LaplaceXYpetsc() { + PetscBool is_finalised; + PetscFinalized(&is_finalised); + + if (!is_finalised) { + // PetscFinalize may already have destroyed this object + KSPDestroy(&ksp); + } + + VecDestroy(&xs); + VecDestroy(&bs); + MatDestroy(&MatA); +} + +Field2D LaplaceXYpetsc::solve(const Field2D& rhs, const Field2D& x0) { + Timer timer("invert"); + + ASSERT1(rhs.getMesh() == localmesh); + ASSERT1(x0.getMesh() == localmesh); + ASSERT1(rhs.getLocation() == location); + ASSERT1(x0.getLocation() == location); + + // Load initial guess x0 into xs and rhs into bs + + for (int x = localmesh->xstart; x <= localmesh->xend; x++) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int ind = globalIndex(x, y); + + PetscScalar val = x0(x, y); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + val = rhs(x, y); + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } + + if (finite_volume) { + solveFiniteVolume(x0); + } else { + solveFiniteDifference(x0); + } + + // Assemble RHS Vector + VecAssemblyBegin(bs); + VecAssemblyEnd(bs); + + // Assemble Trial Solution Vector + VecAssemblyBegin(xs); + VecAssemblyEnd(xs); + + // Solve the system + KSPSolve(ksp, bs, xs); + + KSPConvergedReason reason; + KSPGetConvergedReason(ksp, &reason); + + if (reason <= 0) { + throw BoutException("LaplaceXYpetsc failed to converge. Reason {} ({:d})", + KSPConvergedReasons[reason], static_cast(reason)); + } + + if (save_performance) { + // Update performance monitoring information + n_calls++; + + int iterations = 0; + KSPGetIterationNumber(ksp, &iterations); + + average_iterations = BoutReal(n_calls - 1) / BoutReal(n_calls) * average_iterations + + BoutReal(iterations) / BoutReal(n_calls); + } + + ////////////////////////// + // Copy data into result + + Field2D result; + result.allocate(); + result.setLocation(location); + + for (int x = localmesh->xstart; x <= localmesh->xend; x++) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int ind = globalIndex(x, y); + + PetscScalar val; + VecGetValues(xs, 1, &ind, &val); + result(x, y) = val; + } + } + + // Inner X boundary + if (localmesh->firstX()) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int ind = globalIndex(localmesh->xstart - 1, y); + PetscScalar val; + VecGetValues(xs, 1, &ind, &val); + for (int x = localmesh->xstart - 1; x >= 0; x--) { + result(x, y) = val; + } + } + } + + // Outer X boundary + if (localmesh->lastX()) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int ind = globalIndex(localmesh->xend + 1, y); + PetscScalar val; + VecGetValues(xs, 1, &ind, &val); + for (int x = localmesh->xend + 1; x < localmesh->LocalNx; x++) { + result(x, y) = val; + } + } + } + + // Lower Y boundary + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + if ( + // Should not go into corner cells, finite-volume LaplaceXYpetsc stencil does not include + // them + (finite_volume and (it.ind < localmesh->xstart or it.ind > localmesh->xend)) + + // Only go into first corner cell for finite-difference + or (it.ind < localmesh->xstart - 1 or it.ind > localmesh->xend + 1)) { + continue; + } + int ind = globalIndex(it.ind, localmesh->ystart - 1); + PetscScalar val; + VecGetValues(xs, 1, &ind, &val); + for (int y = localmesh->ystart - 1; y >= 0; y--) { + result(it.ind, y) = val; + } + } + + // Upper Y boundary + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + if ( + // Should not go into corner cells, finite-volume LaplaceXYpetsc stencil does not include + // them + (finite_volume and (it.ind < localmesh->xstart or it.ind > localmesh->xend)) + + // Only go into first corner cell for finite-difference + or (it.ind < localmesh->xstart - 1 or it.ind > localmesh->xend + 1)) { + continue; + } + int ind = globalIndex(it.ind, localmesh->yend + 1); + PetscScalar val; + VecGetValues(xs, 1, &ind, &val); + for (int y = localmesh->yend + 1; y < localmesh->LocalNy; y++) { + result(it.ind, y) = val; + } + } + + return result; +} + +void LaplaceXYpetsc::solveFiniteVolume(const Field2D& x0) { + // Use original LaplaceXYpetsc implementation of passing boundary values for backward + // compatibility + if (localmesh->firstX()) { + if (x_inner_dirichlet) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int ind = globalIndex(localmesh->xstart - 1, y); + + PetscScalar val = x0(localmesh->xstart - 1, y); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + val = 0.5 * (x0(localmesh->xstart - 1, y) + x0(localmesh->xstart, y)); + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } else { + // Inner X boundary (Neumann) + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int ind = globalIndex(localmesh->xstart - 1, y); + + PetscScalar val = x0(localmesh->xstart - 1, y); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + val = 0.0; // x0(localmesh->xstart-1,y) - x0(localmesh->xstart,y); + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } + } + + // Outer X boundary (Dirichlet) + if (localmesh->lastX()) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int ind = globalIndex(localmesh->xend + 1, y); + + PetscScalar val = x0(localmesh->xend + 1, y); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + val = 0.5 * (x0(localmesh->xend, y) + x0(localmesh->xend + 1, y)); + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } + + if (y_bndry == "dirichlet") { + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int ind = globalIndex(it.ind, localmesh->ystart - 1); + + PetscScalar val = x0(it.ind, localmesh->ystart - 1); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + val = 0.5 * (x0(it.ind, localmesh->ystart - 1) + x0(it.ind, localmesh->ystart)); + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int ind = globalIndex(it.ind, localmesh->yend + 1); + + PetscScalar val = x0(it.ind, localmesh->yend + 1); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + val = 0.5 * (x0(it.ind, localmesh->yend + 1) + x0(it.ind, localmesh->yend)); + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } else if (y_bndry == "neumann" or y_bndry == "free_o3") { + // Y boundaries Neumann + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int ind = globalIndex(it.ind, localmesh->ystart - 1); + + PetscScalar val = x0(it.ind, localmesh->ystart - 1); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int ind = globalIndex(it.ind, localmesh->yend + 1); + + PetscScalar val = x0(it.ind, localmesh->yend + 1); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } else { + throw BoutException("Unsupported option for y_bndry"); + } +} + +void LaplaceXYpetsc::solveFiniteDifference(const Field2D& x0) { + // For finite-difference implementation pass boundary values in the same way as for + // the 'Laplacian' solvers - the value to use (for Dirichlet boundary conditions) on + // the boundary (which is half way between grid cell and boundary cell) is passed as + // the value in the first boundary cell. + if (localmesh->firstX()) { + if (x_inner_dirichlet) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int ind = globalIndex(localmesh->xstart - 1, y); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 2. * x0(localmesh->xstart - 1, y) - x0(localmesh->xstart, y); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Pass the value from boundary cell of x0 as the boundary condition to the rhs + val = x0(localmesh->xstart - 1, y); + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } else { + // Inner X boundary (Neumann) + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int ind = globalIndex(localmesh->xstart - 1, y); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = x0(localmesh->xstart, y); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } + } + + // Outer X boundary (Dirichlet) + if (localmesh->lastX()) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + int ind = globalIndex(localmesh->xend + 1, y); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 2. * x0(localmesh->xend + 1, y) - x0(localmesh->xend, y); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Pass the value from boundary cell of x0 as the boundary condition to the rhs + val = x0(localmesh->xend + 1, y); + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } + + if (y_bndry == "dirichlet") { + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, they are treated specially below + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int ind = globalIndex(it.ind, localmesh->ystart - 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = + 2. * x0(it.ind, localmesh->ystart - 1) - x0(it.ind, localmesh->ystart); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Pass the value from boundary cell of x0 as the boundary condition to the rhs + val = x0(it.ind, localmesh->ystart - 1); + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, they are treated specially below + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int ind = globalIndex(it.ind, localmesh->yend + 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = + 2. * x0(it.ind, localmesh->yend + 1) - x0(it.ind, localmesh->yend); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Pass the value from boundary cell of x0 as the boundary condition to the rhs + val = x0(it.ind, localmesh->yend + 1); + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + + // Use free_o3 for the corner boundary cells + if (localmesh->hasBndryLowerY()) { + if (localmesh->firstX()) { + int ind = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 3. * x0(localmesh->xstart - 1, localmesh->ystart) + - 3. * x0(localmesh->xstart - 1, localmesh->ystart + 1) + + x0(localmesh->xstart - 1, localmesh->ystart + 2); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + if (localmesh->lastX()) { + int ind = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 3. * x0(localmesh->xend + 1, localmesh->ystart) + - 3. * x0(localmesh->xend + 1, localmesh->ystart + 1) + + x0(localmesh->xend + 1, localmesh->ystart + 2); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } + if (localmesh->hasBndryUpperY()) { + if (localmesh->firstX()) { + int ind = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 3. * x0(localmesh->xstart - 1, localmesh->yend) + - 3. * x0(localmesh->xstart - 1, localmesh->yend - 1) + + x0(localmesh->xstart - 1, localmesh->yend - 2); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + if (localmesh->lastX()) { + int ind = globalIndex(localmesh->xend + 1, localmesh->yend + 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 3. * x0(localmesh->xend + 1, localmesh->yend) + - 3. * x0(localmesh->xend + 1, localmesh->yend - 1) + + x0(localmesh->xend + 1, localmesh->yend - 2); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } + } else if (y_bndry == "neumann") { + // Y boundaries Neumann + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, they are treated specially below + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int ind = globalIndex(it.ind, localmesh->ystart - 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = x0(it.ind, localmesh->ystart); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + if (localmesh->hasBndryLowerY()) { + if (localmesh->firstX()) { + int ind = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = x0(localmesh->xstart - 1, localmesh->ystart); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + if (localmesh->lastX()) { + int ind = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = x0(localmesh->xend + 1, localmesh->ystart); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } + + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, they are treated specially below + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int ind = globalIndex(it.ind, localmesh->yend + 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = x0(it.ind, localmesh->yend); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + if (localmesh->hasBndryUpperY()) { + if (localmesh->firstX()) { + int ind = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = x0(localmesh->xstart - 1, localmesh->yend); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + if (localmesh->lastX()) { + int ind = globalIndex(localmesh->xend + 1, localmesh->yend + 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = x0(localmesh->xend + 1, localmesh->yend); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } + } else if (y_bndry == "free_o3") { + // Y boundaries free_o3 + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, they are treated specially below + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int ind = globalIndex(it.ind, localmesh->ystart - 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 3. * x0(it.ind, localmesh->ystart) + - 3. * x0(it.ind, localmesh->ystart + 1) + + x0(it.ind, localmesh->ystart + 2); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + if (localmesh->hasBndryLowerY()) { + if (localmesh->firstX()) { + int ind = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 3. * x0(localmesh->xstart - 1, localmesh->ystart) + - 3. * x0(localmesh->xstart - 1, localmesh->ystart + 1) + + x0(localmesh->xstart - 1, localmesh->ystart + 2); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + if (localmesh->lastX()) { + int ind = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 3. * x0(localmesh->xend + 1, localmesh->ystart) + - 3. * x0(localmesh->xend + 1, localmesh->ystart + 1) + + x0(localmesh->xend + 1, localmesh->ystart + 2); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } + + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, they are treated specially below + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + int ind = globalIndex(it.ind, localmesh->yend + 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 3. * x0(it.ind, localmesh->yend) + - 3. * x0(it.ind, localmesh->yend - 1) + + x0(it.ind, localmesh->yend - 2); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + if (localmesh->hasBndryUpperY()) { + if (localmesh->firstX()) { + int ind = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 3. * x0(localmesh->xstart - 1, localmesh->yend) + - 3. * x0(localmesh->xstart - 1, localmesh->yend - 1) + + x0(localmesh->xstart - 1, localmesh->yend - 2); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + if (localmesh->lastX()) { + int ind = globalIndex(localmesh->xend + 1, localmesh->yend + 1); + + // For the boundary value of the initial guess, use the value that would be set by + // applying the boundary condition to the initial guess + PetscScalar val = 3. * x0(localmesh->xend + 1, localmesh->yend) + - 3. * x0(localmesh->xend + 1, localmesh->yend - 1) + + x0(localmesh->xend + 1, localmesh->yend - 2); + VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); + + // Set the value for the rhs of the boundary condition to zero + val = 0.0; + VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); + } + } + } else { + throw BoutException("Unsupported option for y_bndry"); + } +} + +/*! Preconditioner + * NOTE: For generality, this routine does use globalIndex() in the inner loop, although + * this may be slightly less efficient than incrementing an integer for the global index, + * the finite-volume and finite-difference implementations have slightly different + * indexing patterns, so incrementing an integer would be tricky. + */ +int LaplaceXYpetsc::precon(Vec input, Vec result) { + + for (auto itdwn = localmesh->iterateBndryLowerY(); !itdwn.isDone(); itdwn++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (itdwn.ind < localmesh->xstart or itdwn.ind > localmesh->xend) { + continue; + } + const int ind = globalIndex(itdwn.ind, localmesh->ystart - 1); + PetscScalar val; + VecGetValues(input, 1, &ind, &val); + VecSetValues(result, 1, &ind, &val, INSERT_VALUES); + } + for (auto itup = localmesh->iterateBndryUpperY(); !itup.isDone(); itup++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (itup.ind < localmesh->xstart or itup.ind > localmesh->xend) { + continue; + } + const int ind = globalIndex(itup.ind, localmesh->yend + 1); + PetscScalar val; + VecGetValues(input, 1, &ind, &val); + VecSetValues(result, 1, &ind, &val, INSERT_VALUES); + } + + // Load vector x into bvals array + for (int x = xstart; x <= xend; x++) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + const int ind = globalIndex(x, y); + PetscScalar val; + VecGetValues(input, 1, &ind, &val); + bvals(y - localmesh->ystart, x - xstart) = val; + } + } + + // Solve tridiagonal systems using CR solver + cr->solve(bvals, xvals); + + // Save result xvals into y array + for (int x = xstart; x <= xend; x++) { + for (int y = localmesh->ystart; y <= localmesh->yend; y++) { + const int ind = globalIndex(x, y); + PetscScalar val = xvals(y - localmesh->ystart, x - xstart); + VecSetValues(result, 1, &ind, &val, INSERT_VALUES); + } + } + VecAssemblyBegin(result); + VecAssemblyEnd(result); + return 0; +} + +/////////////////////////////////////////////////////////////// + +int LaplaceXYpetsc::localSize() { + + // Bulk of points + const int nx = localmesh->xend - localmesh->xstart + 1; + const int ny = localmesh->yend - localmesh->ystart + 1; + + int n = nx * ny; + + // X boundaries + if (localmesh->firstX()) { + n += ny; + } + if (localmesh->lastX()) { + n += ny; + } + + // Y boundaries + for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + n++; + } + if ((not finite_volume) and localmesh->hasBndryLowerY()) { + if (localmesh->firstX()) { + n++; + } + if (localmesh->lastX()) { + n++; + } + } + for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { + // Should not go into corner cells, LaplaceXYpetsc stencil does not include them + if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { + continue; + } + n++; + } + if ((not finite_volume) and localmesh->hasBndryUpperY()) { + if (localmesh->firstX()) { + n++; + } + if (localmesh->lastX()) { + n++; + } + } + + return n; +} + +int LaplaceXYpetsc::globalIndex(int x, int y) { + if ((x < 0) || (x >= localmesh->LocalNx) || (y < 0) || (y >= localmesh->LocalNy)) { + return -1; // Out of range + } + + // Get the index from a Field2D, round to integer + return static_cast(std::round(indexXY(x, y))); +} + +void LaplaceXYpetsc::savePerformance(Solver& solver, const std::string& name) { + // set flag so that performance monitoring values are calculated + save_performance = true; + + // add values to be saved to the output + if (not name.empty()) { + default_prefix = name; + } + + // add monitor to reset counters/averages for new output timestep + // monitor added to back of queue, so that values are reset after being saved + solver.addMonitor(&monitor, Solver::BACK); +} + +int LaplaceXYpetsc::LaplaceXYMonitor::call(Solver* /*solver*/, BoutReal /*time*/, + int /*iter*/, int /*nout*/) { + laplacexy->output_average_iterations = laplacexy->average_iterations; + + laplacexy->n_calls = 0; + laplacexy->average_iterations = 0.; + + return 0; +} + +void LaplaceXYpetsc::LaplaceXYMonitor::outputVars(Options& output_options, + const std::string& time_dimension) { + output_options[fmt::format("{}_average_iterations", laplacexy->default_prefix)] + .assignRepeat(laplacexy->output_average_iterations, time_dimension); +} + +#endif // BOUT_HAS_PETSC diff --git a/src/invert/laplacexy/impls/petsc/laplacexy-petsc.hxx b/src/invert/laplacexy/impls/petsc/laplacexy-petsc.hxx new file mode 100644 index 0000000000..27d25cf9a7 --- /dev/null +++ b/src/invert/laplacexy/impls/petsc/laplacexy-petsc.hxx @@ -0,0 +1,209 @@ +/************************************************************************** + * Laplacian solver in 2D (X-Y) + * + * Equation solved is: + * + * Div( A * Grad_perp(x) ) + B*x = b + * + * Intended for use in solving n = 0 component of potential + * from inversion of vorticity equation + * + ************************************************************************** + * Copyright 2015 B.Dudson + * + * 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 . + * + **************************************************************************/ + +#ifndef BOUT_LAPLACE_XY_PETSC_H +#define BOUT_LAPLACE_XY_PETSC_H + +#include "bout/build_defines.hxx" +#include "bout/invert/laplacexy.hxx" + +#if !BOUT_HAS_PETSC + +namespace { +RegisterUnavailableLaplaceXY + registerlaplacexypetsc("petsc", "BOUT++ was not configured with PETSc"); +} + +#else // BOUT_HAS_PETSC + +#include "bout/bout_types.hxx" +#include "bout/cyclic_reduction.hxx" +#include "bout/field2d.hxx" +#include "bout/mesh.hxx" +#include "bout/monitor.hxx" +#include "bout/petsclib.hxx" +#include "bout/utils.hxx" + +#include +#include + +class Options; +class Solver; + +class LaplaceXYpetsc : public LaplaceXY { +public: + LaplaceXYpetsc(Mesh* m = nullptr, Options* opt = nullptr, CELL_LOC loc = CELL_CENTRE); + LaplaceXYpetsc(const LaplaceXYpetsc&) = delete; + LaplaceXYpetsc(LaplaceXYpetsc&&) = delete; + LaplaceXYpetsc& operator=(const LaplaceXYpetsc&) = delete; + LaplaceXYpetsc& operator=(LaplaceXYpetsc&&) = delete; + ~LaplaceXYpetsc() override; + + /*! + * Set coefficients (A, B) in equation: + * Div( A * Grad_perp(x) ) + B*x = b + */ + void setCoefs(const Field2D& A, const Field2D& B) override; + + /*! + * Solve Laplacian in X-Y + * + * Inputs + * ====== + * + * rhs - The field to be inverted. This must be allocated + * and contain valid data. + * x0 - Initial guess at the solution. If this is unallocated + * then an initial guess of zero will be used. + * + * Returns + * ======= + * + * The solution as a Field2D. On failure an exception will be raised + * + */ + Field2D solve(const Field2D& rhs, const Field2D& x0) override; + + /*! + * Preconditioner function + * This is called by PETSc via a static function. + * and should not be called by external users + */ + int precon(Vec x, Vec y); + + /*! + * If this method is called, save some performance monitoring information + */ + void savePerformance(Solver& solver, const std::string& name = ""); + +private: + PetscLib lib; ///< Requires PETSc library + Mat MatA = nullptr; ///< Matrix to be inverted + Vec xs = nullptr; ///< Solution vector + Vec bs = nullptr; ///< RHS vectors + KSP ksp = nullptr; ///< Krylov Subspace solver + PC pc = nullptr; ///< Preconditioner + + Mesh* localmesh; ///< The mesh this operates on, provides metrics and communication + + /// default prefix for writing performance logging variables + std::string default_prefix; + + // Preconditioner + int xstart, xend; + int nloc, nsys; + Matrix acoef, bcoef, ccoef, xvals, bvals; + std::unique_ptr> cr; ///< Tridiagonal solver + + // Use finite volume or finite difference discretization + bool finite_volume{true}; + + // Y derivatives + bool include_y_derivs; // Include Y derivative terms? + + // Boundary conditions + bool x_inner_dirichlet; // Dirichlet on inner X boundary? + bool x_outer_dirichlet{false}; // Dirichlet on outer X boundary? + std::string y_bndry{"neumann"}; // Boundary condition for y-boundary + + // Location of the rhs and solution + CELL_LOC location; + + /*! + * Number of grid points on this processor + */ + int localSize(); + + /*! + * Return the communicator for XY + */ + MPI_Comm communicator(); + + /*! + * Return the global index of a local (x,y) coordinate + * including guard cells. + * Boundary cells have a global index of -1 + * + * To do this, a Field2D (indexXY) is used to store + * the index as a floating point number which is then rounded + * to an integer. Guard cells are filled by communication + * so no additional logic is needed in Mesh. + */ + int globalIndex(int x, int y); + Field2D indexXY; ///< Global index (integer stored as BoutReal) + + // Save performance information? + bool save_performance = false; + + // Running average of number of iterations taken for solve in each output timestep + BoutReal average_iterations = 0.; + + // Variable to store the final result of average_iterations, since output is + // written after all other monitors have been called, and average_iterations + // must be reset in the monitor + BoutReal output_average_iterations = 0.; + + // Running total of number of calls to the solver in each output timestep + int n_calls = 0; + + // Utility methods + void setPreallocationFiniteVolume(PetscInt* d_nnz, PetscInt* o_nnz); + void setPreallocationFiniteDifference(PetscInt* d_nnz, PetscInt* o_nnz); + void setMatrixElementsFiniteVolume(const Field2D& A, const Field2D& B); + void setMatrixElementsFiniteDifference(const Field2D& A, const Field2D& B); + void solveFiniteVolume(const Field2D& x0); + void solveFiniteDifference(const Field2D& x0); + + // Monitor class used to reset performance-monitoring variables for a new + // output timestep + friend class LaplaceXYMonitor; + class LaplaceXYMonitor : public Monitor { + public: + LaplaceXYMonitor(LaplaceXYpetsc& owner) : laplacexy(&owner) {} + + int call(Solver* /*solver*/, BoutReal /*time*/, int /*iter*/, int /*nout*/) override; + void outputVars(Options& output_options, const std::string& time_dimension) override; + + private: + // LaplaceXY object that this monitor belongs to + LaplaceXYpetsc* laplacexy; + }; + + LaplaceXYMonitor monitor; +}; + +namespace { +const inline RegisterLaplaceXY registerlaplacexypetsc{"petsc"}; +} + +#endif // BOUT_HAS_PETSC +#endif // BOUT_LAPLACE_XY_PETSC_H diff --git a/src/invert/laplacexy2/laplacexy2.cxx b/src/invert/laplacexy/impls/petsc2/laplacexy-petsc2.cxx similarity index 90% rename from src/invert/laplacexy2/laplacexy2.cxx rename to src/invert/laplacexy/impls/petsc2/laplacexy-petsc2.cxx index 713fd8e68f..01019466a8 100644 --- a/src/invert/laplacexy2/laplacexy2.cxx +++ b/src/invert/laplacexy/impls/petsc2/laplacexy-petsc2.cxx @@ -2,26 +2,34 @@ #if BOUT_HAS_PETSC and not BOUT_USE_METRIC_3D -#include -#include -#include -#include -#include -#include -#include +#include "laplacexy-petsc2.hxx" + +#include "bout/assert.hxx" +#include "bout/bout_types.hxx" +#include "bout/boutcomm.hxx" +#include "bout/coordinates.hxx" +#include "bout/field2d.hxx" +#include "bout/globalindexer.hxx" +#include "bout/globals.hxx" +#include "bout/operatorstencil.hxx" +#include "bout/options.hxx" +#include "bout/petsc_interface.hxx" +#include "bout/region.hxx" +#include "bout/sys/range.hxx" +#include "bout/sys/timer.hxx" + +#include #include -#include - namespace { Ind2D index2d(Mesh* mesh, int x, int y) { int ny = mesh->LocalNy; - return Ind2D(x * ny + y, ny, 1); + return Ind2D((x * ny) + y, ny, 1); } } // namespace -LaplaceXY2::LaplaceXY2(Mesh* m, Options* opt, const CELL_LOC loc) +LaplaceXYpetsc2::LaplaceXYpetsc2(Mesh* m, Options* opt, const CELL_LOC loc) : localmesh(m == nullptr ? bout::globals::mesh : m), indexConverter(std::make_shared>( localmesh, squareStencil(localmesh))), @@ -100,12 +108,12 @@ LaplaceXY2::LaplaceXY2(Mesh* m, Options* opt, const CELL_LOC loc) // Decide boundary condititions if (localmesh->periodicY(localmesh->xstart)) { // Periodic in Y, so in the core - opt->get("core_bndry_dirichlet", x_inner_dirichlet, false); + x_inner_dirichlet = (*opt)["core_bndry_dirichlet"].withDefault(false); } else { // Non-periodic, so in the PF region - opt->get("pf_bndry_dirichlet", x_inner_dirichlet, true); + x_inner_dirichlet = (*opt)["pf_bndry_dirichlet"].withDefault(true); } - opt->get("y_bndry_dirichlet", y_bndry_dirichlet, false); + y_bndry_dirichlet = (*opt)["y_bndry_dirichlet"].withDefault(false); /////////////////////////////////////////////////// // Including Y derivatives? @@ -120,10 +128,10 @@ LaplaceXY2::LaplaceXY2(Mesh* m, Options* opt, const CELL_LOC loc) Field2D zero(0., localmesh); one.setLocation(location); zero.setLocation(location); - setCoefs(one, zero); + LaplaceXYpetsc2::setCoefs(one, zero); } -void LaplaceXY2::setCoefs(const Field2D& A, const Field2D& B) { +void LaplaceXYpetsc2::setCoefs(const Field2D& A, const Field2D& B) { Timer timer("invert"); ASSERT1(A.getMesh() == localmesh); @@ -290,7 +298,7 @@ void LaplaceXY2::setCoefs(const Field2D& A, const Field2D& B) { #endif } -LaplaceXY2::~LaplaceXY2() { +LaplaceXYpetsc2::~LaplaceXYpetsc2() { PetscBool is_finalised; PetscFinalized(&is_finalised); @@ -300,7 +308,7 @@ LaplaceXY2::~LaplaceXY2() { } } -Field2D LaplaceXY2::solve(const Field2D& rhs, const Field2D& x0) { +Field2D LaplaceXYpetsc2::solve(const Field2D& rhs, const Field2D& x0) { Timer timer("invert"); ASSERT1(rhs.getMesh() == localmesh); @@ -310,7 +318,8 @@ Field2D LaplaceXY2::solve(const Field2D& rhs, const Field2D& x0) { // Load initial guess x0 into xs and rhs into bs - PetscVector xs(x0, indexConverter), bs(rhs, indexConverter); + PetscVector xs(x0, indexConverter); + PetscVector bs(rhs, indexConverter); if (localmesh->firstX()) { if (x_inner_dirichlet) { @@ -381,11 +390,11 @@ Field2D LaplaceXY2::solve(const Field2D& rhs, const Field2D& x0) { // Solve the system KSPSolve(ksp, *bs.get(), *xs.get()); - KSPConvergedReason reason; + KSPConvergedReason reason = KSP_CONVERGED_ITERATING; KSPGetConvergedReason(ksp, &reason); if (reason <= 0) { - throw BoutException("LaplaceXY2 failed to converge. Reason {} ({:d})", + throw BoutException("LaplaceXYpetsc2 failed to converge. Reason {} ({:d})", KSPConvergedReasons[reason], static_cast(reason)); } diff --git a/include/bout/invert/laplacexy2.hxx b/src/invert/laplacexy/impls/petsc2/laplacexy-petsc2.hxx similarity index 61% rename from include/bout/invert/laplacexy2.hxx rename to src/invert/laplacexy/impls/petsc2/laplacexy-petsc2.hxx index 51f75f467d..eb1be636f2 100644 --- a/include/bout/invert/laplacexy2.hxx +++ b/src/invert/laplacexy/impls/petsc2/laplacexy-petsc2.hxx @@ -30,63 +30,47 @@ * **************************************************************************/ -#ifndef BOUT_LAPLACE_XY2_H -#define BOUT_LAPLACE_XY2_H +#ifndef BOUT_LAPLACE_XY_PETSC2_H +#define BOUT_LAPLACE_XY_PETSC2_H #include "bout/build_defines.hxx" - -#if (not BOUT_HAS_PETSC) or BOUT_USE_METRIC_3D -// If no PETSc or 3D metrics - -#warning LaplaceXY2 requires PETSc and 2D metrics. No LaplaceXY2 available - -#include -#include -#include - -/*! - * Create a dummy class so that code will compile - * without PETSc, but will throw an exception if - * LaplaceXY is used. - */ -class LaplaceXY2 { -public: - LaplaceXY2(Mesh* UNUSED(m) = nullptr, Options* UNUSED(opt) = nullptr, - const CELL_LOC UNUSED(loc) = CELL_CENTRE) { - throw BoutException( - "LaplaceXY2 requires PETSc and 2D metrics. No LaplaceXY2 available"); - } - void setCoefs(const Field2D& UNUSED(A), const Field2D& UNUSED(B)) {} - Field2D solve(const Field2D& UNUSED(rhs), const Field2D& UNUSED(x0)) { - throw BoutException( - "LaplaceXY2 requires PETSc and 2D metrics. No LaplaceXY2 available"); - } -}; - -#else // BOUT_HAS_PETSC and 2D metrics - -#include "bout/utils.hxx" -#include -#include -#include -#include - -class LaplaceXY2 { +#include "bout/invert/laplacexy.hxx" + +#if !BOUT_HAS_PETSC +namespace { +RegisterUnavailableLaplaceXY + registerlaplacexypetsc2("petsc2", "BOUT++ was not configured with PETSc"); +} + +#elif BOUT_USE_METRIC_3D +namespace { +RegisterUnavailableLaplaceXY + registerlaplacexypetsc2("petsc2", "BOUT++ was configured with 3D metrics"); +} + +#else // BOUT_HAS_PETSC + +#include "bout/bout_types.hxx" +#include "bout/field2d.hxx" +#include "bout/globalindexer.hxx" +#include "bout/mesh.hxx" +#include "bout/petsc_interface.hxx" +#include "bout/petsclib.hxx" + +class LaplaceXYpetsc2 : public LaplaceXY { public: - /*! - * Constructor - */ - LaplaceXY2(Mesh* m = nullptr, Options* opt = nullptr, const CELL_LOC loc = CELL_CENTRE); - /*! - * Destructor - */ - ~LaplaceXY2(); + LaplaceXYpetsc2(Mesh* m = nullptr, Options* opt = nullptr, CELL_LOC loc = CELL_CENTRE); + LaplaceXYpetsc2(const LaplaceXYpetsc2&) = default; + LaplaceXYpetsc2(LaplaceXYpetsc2&&) = delete; + LaplaceXYpetsc2& operator=(const LaplaceXYpetsc2&) = default; + LaplaceXYpetsc2& operator=(LaplaceXYpetsc2&&) = delete; + ~LaplaceXYpetsc2() override; /*! * Set coefficients (A, B) in equation: * Div( A * Grad_perp(x) ) + B*x = b */ - void setCoefs(const Field2D& A, const Field2D& B); + void setCoefs(const Field2D& A, const Field2D& B) override; /*! * Solve Laplacian in X-Y @@ -105,7 +89,7 @@ public: * The solution as a Field2D. On failure an exception will be raised * */ - Field2D solve(const Field2D& rhs, const Field2D& x0); + Field2D solve(const Field2D& rhs, const Field2D& x0) override; /*! * Preconditioner function @@ -121,8 +105,8 @@ private: IndexerPtr indexConverter; PetscMatrix matrix; ///< Matrix to be inverted - KSP ksp; ///< Krylov Subspace solver - PC pc; ///< Preconditioner + KSP ksp = nullptr; ///< Krylov Subspace solver + PC pc = nullptr; ///< Preconditioner // Y derivatives bool include_y_derivs; // Include Y derivative terms? @@ -140,5 +124,9 @@ private: MPI_Comm communicator(); }; +namespace { +const inline RegisterLaplaceXY registerlaplacexypetsc2{"petsc2"}; +} + #endif // BOUT_HAS_PETSC -#endif // BOUT_LAPLACE_XY2_H +#endif // BOUT_LAPLACE_XY_PETSC2_H diff --git a/src/invert/laplacexy/laplacexy.cxx b/src/invert/laplacexy/laplacexy.cxx index bdd22e29bd..3bac2d9d2b 100644 --- a/src/invert/laplacexy/laplacexy.cxx +++ b/src/invert/laplacexy/laplacexy.cxx @@ -1,1889 +1,10 @@ -#include "bout/build_defines.hxx" - -#if BOUT_HAS_PETSC +// NOLINTBEGIN(misc-include-cleaner, unused-includes) +#include "impls/hypre/laplacexy-hypre.hxx" +#include "impls/petsc/laplacexy-petsc.hxx" +#include "impls/petsc2/laplacexy-petsc2.hxx" +// NOLINTEND(misc-include-cleaner, unused-includes) #include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -static PetscErrorCode laplacePCapply(PC pc, Vec x, Vec y) { - int ierr; - - // Get the context - LaplaceXY* s; - ierr = PCShellGetContext(pc, reinterpret_cast(&s)); - CHKERRQ(ierr); - - PetscFunctionReturn(s->precon(x, y)); -} - -LaplaceXY::LaplaceXY(Mesh* m, Options* opt, const CELL_LOC loc) - : lib(opt == nullptr ? &(Options::root()["laplacexy"]) : opt), - localmesh(m == nullptr ? bout::globals::mesh : m), location(loc), monitor(*this) { - Timer timer("invert"); - - if (opt == nullptr) { - // If no options supplied, use default - opt = &(Options::root()["laplacexy"]); - } - - finite_volume = - (*opt)["finite_volume"] - .doc("Use finite volume rather than finite difference discretisation.") - .withDefault(true); - - /////////////////////////////////////////////////// - // Boundary condititions options - if (localmesh->periodicY(localmesh->xstart)) { - // Periodic in Y, so in the core - x_inner_dirichlet = (*opt)["core_bndry_dirichlet"].withDefault(false); - } else { - // Non-periodic, so in the PF region - x_inner_dirichlet = (*opt)["pf_bndry_dirichlet"].withDefault(true); - } - if ((*opt)["y_bndry_dirichlet"].isSet()) { - throw BoutException("y_bndry_dirichlet has been deprecated. Use y_bndry=dirichlet " - "instead."); - } else { - y_bndry = (*opt)["y_bndry"].withDefault("neumann"); - } - - // Check value of y_bndry is a supported option - if (not(y_bndry == "dirichlet" or y_bndry == "neumann" or y_bndry == "free_o3")) { - - throw BoutException("Unrecognized option '{}' for laplacexy:ybndry", y_bndry); - } - - if (not finite_volume) { - // Check we can use corner cells - if (not localmesh->include_corner_cells) { - throw BoutException( - "Finite difference form of LaplaceXY allows non-orthogonal x- and " - "y-directions, so requires mesh:include_corner_cells=true."); - } - } - - // Use name of options section as the default prefix for performance logging variables - default_prefix = opt->name(); - - // Get MPI communicator - auto comm = BoutComm::get(); - - // Local size - const int localN = localSize(); - - // Create Vectors - VecCreate(comm, &xs); - VecSetSizes(xs, localN, PETSC_DETERMINE); - VecSetFromOptions(xs); - VecDuplicate(xs, &bs); - - // Set size of Matrix on each processor to localN x localN - MatCreate(comm, &MatA); - MatSetSizes(MatA, localN, localN, PETSC_DETERMINE, PETSC_DETERMINE); - MatSetFromOptions(MatA); - - ////////////////////////////////////////////////// - // Specify local indices. This creates a mapping - // from local indices to index, using a Field2D object - - indexXY = -1; // Set all points to -1, indicating out of domain - - int ind = 0; - - // Y boundaries - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - indexXY(it.ind, localmesh->ystart - 1) = ind++; - } - if ((not finite_volume) and localmesh->hasBndryLowerY()) { - // Corner boundary cells - if (localmesh->firstX()) { - indexXY(localmesh->xstart - 1, localmesh->ystart - 1) = ind++; - } - if (localmesh->lastX()) { - indexXY(localmesh->xend + 1, localmesh->ystart - 1) = ind++; - } - } - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - indexXY(it.ind, localmesh->yend + 1) = ind++; - } - if ((not finite_volume) and localmesh->hasBndryUpperY()) { - // Corner boundary cells - if (localmesh->firstX()) { - indexXY(localmesh->xstart - 1, localmesh->yend + 1) = ind++; - } - if (localmesh->lastX()) { - indexXY(localmesh->xend + 1, localmesh->yend + 1) = ind++; - } - } - - xstart = localmesh->xstart; - if (localmesh->firstX()) { - xstart -= 1; // Include X guard cells - } - xend = localmesh->xend; - if (localmesh->lastX()) { - xend += 1; - } - for (int x = xstart; x <= xend; x++) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - indexXY(x, y) = ind++; - } - } - - ASSERT1(ind == localN); // Reached end of range - - ////////////////////////////////////////////////// - // Allocate storage for preconditioner - - nloc = xend - xstart + 1; // Number of X points on this processor - nsys = localmesh->yend - localmesh->ystart + 1; // Number of separate Y slices - - acoef.reallocate(nsys, nloc); - bcoef.reallocate(nsys, nloc); - ccoef.reallocate(nsys, nloc); - xvals.reallocate(nsys, nloc); - bvals.reallocate(nsys, nloc); - - // Create a cyclic reduction object - cr = bout::utils::make_unique>(localmesh->getXcomm(), nloc); - - ////////////////////////////////////////////////// - // Pre-allocate PETSc storage - - PetscInt *d_nnz, *o_nnz; - PetscMalloc((localN) * sizeof(PetscInt), &d_nnz); - PetscMalloc((localN) * sizeof(PetscInt), &o_nnz); - - if (finite_volume) { - setPreallocationFiniteVolume(d_nnz, o_nnz); - } else { - setPreallocationFiniteDifference(d_nnz, o_nnz); - } - // Pre-allocate - MatMPIAIJSetPreallocation(MatA, 0, d_nnz, 0, o_nnz); - MatSetUp(MatA); - - PetscFree(d_nnz); - PetscFree(o_nnz); - - // Determine which row/columns of the matrix are locally owned - int Istart, Iend; - MatGetOwnershipRange(MatA, &Istart, &Iend); - - // Convert indexXY from local index to global index - indexXY += Istart; - - // Now communicate to fill guard cells - // Note, this includes corner cells if necessary - localmesh->communicate(indexXY); - - ////////////////////////////////////////////////// - // Set up KSP - - // Declare KSP Context - KSPCreate(comm, &ksp); - - // Configure Linear Solver - - const bool direct = (*opt)["direct"].doc("Use a direct LU solver").withDefault(false); - - if (direct) { - KSPGetPC(ksp, &pc); - PCSetType(pc, PCLU); -#if PETSC_VERSION_GE(3, 9, 0) - PCFactorSetMatSolverType(pc, "mumps"); -#else - PCFactorSetMatSolverPackage(pc, "mumps"); -#endif - } else { - - // Convergence Parameters. Solution is considered converged if |r_k| < max( rtol * |b| , atol ) - // where r_k = b - Ax_k. The solution is considered diverged if |r_k| > dtol * |b|. - - const BoutReal rtol = (*opt)["rtol"].doc("Relative tolerance").withDefault(1e-5); - const BoutReal atol = - (*opt)["atol"] - .doc("Absolute tolerance. The solution is considered converged if |Ax-b| " - "< max( rtol * |b| , atol )") - .withDefault(1e-10); - const BoutReal dtol = - (*opt)["dtol"] - .doc("The solution is considered diverged if |Ax-b| > dtol * |b|") - .withDefault(1e3); - const int maxits = (*opt)["maxits"].doc("Maximum iterations").withDefault(100000); - - // Get KSP Solver Type - const std::string ksptype = - (*opt)["ksptype"].doc("KSP solver type").withDefault("gmres"); - - // Get PC type - const std::string pctype = - (*opt)["pctype"].doc("Preconditioner type").withDefault("none"); - - KSPSetType(ksp, ksptype.c_str()); - KSPSetTolerances(ksp, rtol, atol, dtol, maxits); - - KSPSetInitialGuessNonzero(ksp, static_cast(true)); - - KSPGetPC(ksp, &pc); - PCSetType(pc, pctype.c_str()); - - if (pctype == "shell") { - // Using tridiagonal solver as preconditioner - PCShellSetApply(pc, laplacePCapply); - PCShellSetContext(pc, this); - - const bool rightprec = - (*opt)["rightprec"].doc("Use right preconditioning?").withDefault(true); - if (rightprec) { - KSPSetPCSide(ksp, PC_RIGHT); // Right preconditioning - } else { - KSPSetPCSide(ksp, PC_LEFT); // Left preconditioning - } - } - } - - lib.setOptionsFromInputFile(ksp); - - /////////////////////////////////////////////////// - // Including Y derivatives? - - include_y_derivs = (*opt)["include_y_derivs"] - .doc("Include Y derivatives in operator to invert?") - .withDefault(true); - - /////////////////////////////////////////////////// - // Set the default coefficients - Field2D one(1., localmesh); - Field2D zero(0., localmesh); - one.setLocation(location); - zero.setLocation(location); - setCoefs(one, zero); -} - -void LaplaceXY::setPreallocationFiniteVolume(PetscInt* d_nnz, PetscInt* o_nnz) { - const int localN = localSize(); - - // This discretisation uses a 5-point stencil - for (int i = 0; i < localN; i++) { - // Non-zero elements on this processor - d_nnz[i] = 5; // Star pattern in 2D - // Non-zero elements on neighboring processor - o_nnz[i] = 0; - } - - // X boundaries - if (localmesh->firstX()) { - // Lower X boundary - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - const int localIndex = globalIndex(localmesh->xstart - 1, y); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - - d_nnz[localIndex] = 2; // Diagonal sub-matrix - o_nnz[localIndex] = 0; // Off-diagonal sub-matrix - } - } else { - // On another processor - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - const int localIndex = globalIndex(localmesh->xstart, y); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] -= 1; - o_nnz[localIndex] += 1; - } - } - if (localmesh->lastX()) { - // Upper X boundary - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - const int localIndex = globalIndex(localmesh->xend + 1, y); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = 2; // Diagonal sub-matrix - o_nnz[localIndex] = 0; // Off-diagonal sub-matrix - } - } else { - // On another processor - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - const int localIndex = globalIndex(localmesh->xend, y); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] -= 1; - o_nnz[localIndex] += 1; - } - } - // Y boundaries - - for (int x = localmesh->xstart; x <= localmesh->xend; x++) { - // Default to no boundary - // NOTE: This assumes that communications in Y are to other - // processors. If Y is communicated with this processor (e.g. NYPE=1) - // then this will result in PETSc warnings about out of range allocations - { - const int localIndex = globalIndex(x, localmesh->ystart); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - // d_nnz[localIndex] -= 1; // Note: Slightly inefficient - o_nnz[localIndex] += 1; - } - { - const int localIndex = globalIndex(x, localmesh->yend); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - // d_nnz[localIndex] -= 1; // Note: Slightly inefficient - o_nnz[localIndex] += 1; - } - } - - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - { - const int localIndex = globalIndex(it.ind, localmesh->ystart - 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = 2; // Diagonal sub-matrix - o_nnz[localIndex] = 0; // Off-diagonal sub-matrix - } - { - const int localIndex = globalIndex(it.ind, localmesh->ystart); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] += 1; - o_nnz[localIndex] -= 1; - } - } - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - { - const int localIndex = globalIndex(it.ind, localmesh->yend + 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = 2; // Diagonal sub-matrix - o_nnz[localIndex] = 0; // Off-diagonal sub-matrix - } - { - const int localIndex = globalIndex(it.ind, localmesh->yend); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] += 1; - o_nnz[localIndex] -= 1; - } - } -} - -void LaplaceXY::setPreallocationFiniteDifference(PetscInt* d_nnz, PetscInt* o_nnz) { - const int localN = localSize(); - - // This discretisation uses a 9-point stencil - for (int i = 0; i < localN; i++) { - // Non-zero elements on this processor - d_nnz[i] = 9; // Square pattern in 2D - // Non-zero elements on neighboring processor - o_nnz[i] = 0; - } - - // X boundaries - if (localmesh->firstX()) { - // Lower X boundary - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - const int localIndex = globalIndex(localmesh->xstart - 1, y); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - - d_nnz[localIndex] = 2; // Diagonal sub-matrix - o_nnz[localIndex] = 0; // Off-diagonal sub-matrix - } - } else { - // On another processor - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - const int localIndex = globalIndex(localmesh->xstart, y); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] -= 3; - o_nnz[localIndex] += 3; - } - } - if (localmesh->lastX()) { - // Upper X boundary - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - const int localIndex = globalIndex(localmesh->xend + 1, y); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = 2; // Diagonal sub-matrix - o_nnz[localIndex] = 0; // Off-diagonal sub-matrix - } - } else { - // On another processor - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - const int localIndex = globalIndex(localmesh->xend, y); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] -= 3; - o_nnz[localIndex] += 3; - } - } - // Y boundaries - const int y_bndry_stencil_size = (y_bndry == "free_o3") ? 4 : 2; - - for (int x = localmesh->xstart; x <= localmesh->xend; x++) { - // Default to no boundary - // NOTE: This assumes that communications in Y are to other - // processors. If Y is communicated with this processor (e.g. NYPE=1) - // then this will result in PETSc warnings about out of range allocations - { - const int localIndex = globalIndex(x, localmesh->ystart); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - // d_nnz[localIndex] -= 3; // Note: Slightly inefficient - o_nnz[localIndex] += 3; - } - { - const int localIndex = globalIndex(x, localmesh->yend); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - // d_nnz[localIndex] -= 3; // Note: Slightly inefficient - o_nnz[localIndex] += 3; - } - } - - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, they are handled specially below - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - { - const int localIndex = globalIndex(it.ind, localmesh->ystart - 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = y_bndry_stencil_size; // Diagonal sub-matrix - o_nnz[localIndex] = 0; // Off-diagonal sub-matrix - } - { - const int localIndex = globalIndex(it.ind, localmesh->ystart); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - //d_nnz[localIndex] += 3; - o_nnz[localIndex] -= 3; - } - } - if (localmesh->hasBndryLowerY()) { - if (y_bndry == "dirichlet") { - // special handling for the corners, since we use a free_o3 y-boundary - // condition just in the corners when y_bndry=="dirichlet" - if (localmesh->firstX()) { - const int localIndex = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = 4; - } - if (localmesh->lastX()) { - const int localIndex = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = 4; - } - } else { - if (localmesh->firstX()) { - const int localIndex = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = y_bndry_stencil_size; - } - if (localmesh->lastX()) { - const int localIndex = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = y_bndry_stencil_size; - } - } - } - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, they are handled specially below - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - { - const int localIndex = globalIndex(it.ind, localmesh->yend + 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = y_bndry_stencil_size; // Diagonal sub-matrix - o_nnz[localIndex] = 0; // Off-diagonal sub-matrix - } - { - const int localIndex = globalIndex(it.ind, localmesh->yend); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - //d_nnz[localIndex] += 3; - o_nnz[localIndex] -= 3; - } - } - if (localmesh->hasBndryUpperY()) { - if (y_bndry == "dirichlet") { - // special handling for the corners, since we use a free_o3 y-boundary - // condition just in the corners when y_bndry=="dirichlet" - if (localmesh->firstX()) { - const int localIndex = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = 4; - } - if (localmesh->lastX()) { - const int localIndex = globalIndex(localmesh->xend + 1, localmesh->yend + 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = 4; - } - } else { - if (localmesh->firstX()) { - const int localIndex = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = y_bndry_stencil_size; - } - if (localmesh->lastX()) { - const int localIndex = globalIndex(localmesh->xend + 1, localmesh->yend + 1); - ASSERT1((localIndex >= 0) && (localIndex < localN)); - d_nnz[localIndex] = y_bndry_stencil_size; - } - } - } -} - -void LaplaceXY::setCoefs(const Field2D& A, const Field2D& B) { - Timer timer("invert"); - - ASSERT1(A.getMesh() == localmesh); - ASSERT1(B.getMesh() == localmesh); - ASSERT1(A.getLocation() == location); - ASSERT1(B.getLocation() == location); - - if (finite_volume) { - setMatrixElementsFiniteVolume(A, B); - } else { - setMatrixElementsFiniteDifference(A, B); - } - - // X boundaries - if (localmesh->firstX()) { - if (x_inner_dirichlet) { - - // Dirichlet on inner X boundary - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int row = globalIndex(localmesh->xstart - 1, y); - PetscScalar val = 0.5; - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - int col = globalIndex(localmesh->xstart, y); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - // Preconditioner - bcoef(y - localmesh->ystart, 0) = 0.5; - ccoef(y - localmesh->ystart, 0) = 0.5; - } - - } else { - - // Neumann on inner X boundary - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int row = globalIndex(localmesh->xstart - 1, y); - PetscScalar val = 1.0; - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - int col = globalIndex(localmesh->xstart, y); - val = -1.0; - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - // Preconditioner - bcoef(y - localmesh->ystart, 0) = 1.0; - ccoef(y - localmesh->ystart, 0) = -1.0; - } - } - } - if (localmesh->lastX()) { - // Dirichlet on outer X boundary - - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int row = globalIndex(localmesh->xend + 1, y); - PetscScalar val = 0.5; - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - int col = globalIndex(localmesh->xend, y); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - // Preconditioner - acoef(y - localmesh->ystart, localmesh->xend + 1 - xstart) = 0.5; - bcoef(y - localmesh->ystart, localmesh->xend + 1 - xstart) = 0.5; - } - } - - if (y_bndry == "dirichlet") { - // Dirichlet on Y boundaries - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int row = globalIndex(it.ind, localmesh->ystart - 1); - PetscScalar val = 0.5; - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - int col = globalIndex(it.ind, localmesh->ystart); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } - - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int row = globalIndex(it.ind, localmesh->yend + 1); - PetscScalar val = 0.5; - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - int col = globalIndex(it.ind, localmesh->yend); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } - } else if (y_bndry == "neumann") { - // Neumann on Y boundaries - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int row = globalIndex(it.ind, localmesh->ystart - 1); - PetscScalar val = 1.0; - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -1.0; - int col = globalIndex(it.ind, localmesh->ystart); - - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } - - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int row = globalIndex(it.ind, localmesh->yend + 1); - PetscScalar val = 1.0; - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -1.0; - int col = globalIndex(it.ind, localmesh->yend); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } - } else if (y_bndry == "free_o3") { - // 'free_o3' extrapolating boundary condition on Y boundaries - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int row = globalIndex(it.ind, localmesh->ystart - 1); - PetscScalar val = 1.0; - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -3.0; - int col = globalIndex(it.ind, localmesh->ystart); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = 3.0; - col = globalIndex(it.ind, localmesh->ystart + 1); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = -1.0; - col = globalIndex(it.ind, localmesh->ystart + 2); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } - - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int row = globalIndex(it.ind, localmesh->yend + 1); - PetscScalar val = 1.0; - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -3.0; - int col = globalIndex(it.ind, localmesh->yend); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = 3.0; - col = globalIndex(it.ind, localmesh->yend - 1); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = -1.0; - col = globalIndex(it.ind, localmesh->yend - 2); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } - } else { - throw BoutException("Unsupported option for y_bndry"); - } - - if (not finite_volume) { - // Handle corner boundary cells in case we need to include D2DXDY - // Apply the y-boundary-condition to the cells in the x-boundary - this is an - // arbitrary choice, cf. connections around the X-point - - if (localmesh->hasBndryLowerY()) { - if (localmesh->firstX()) { - if (y_bndry == "neumann") { - // Neumann y-bc - // f(xs-1,ys-1) = f(xs-1,ys) - PetscScalar val = 1.0; - int row = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -1.0; - int col = globalIndex(localmesh->xstart - 1, localmesh->ystart); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } else if (y_bndry == "free_o3" or y_bndry == "dirichlet") { - // 'free_o3' extrapolating boundary condition on Y boundaries - // f(xs-1,ys-1) = 3*f(xs-1,ys) - 3*f(xs-1,ys+1) + f(xs-1,ys+2) - // - // Use free_o3 at the corners for Dirichlet y-boundaries because we don't know - // what value to pass for the corner - PetscScalar val = 1.0; - int row = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -3.0; - int col = globalIndex(localmesh->xstart - 1, localmesh->ystart); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = 3.0; - col = globalIndex(localmesh->xstart - 1, localmesh->ystart + 1); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = -1.0; - col = globalIndex(localmesh->xstart - 1, localmesh->ystart + 2); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } else { - throw BoutException("Unsupported option for y_bndry"); - } - } - if (localmesh->lastX()) { - if (y_bndry == "neumann") { - // Neumann y-bc - // f(xe+1,ys-1) = f(xe+1,ys) - PetscScalar val = 1.0; - int row = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -1.0; - int col = globalIndex(localmesh->xend + 1, localmesh->ystart); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } else if (y_bndry == "free_o3" or y_bndry == "dirichlet") { - // 'free_o3' extrapolating boundary condition on Y boundaries - // f(xe+1,ys-1) = 3*f(xe+1,ys) - 3*f(xe+1,ys+1) + f(xe+1,ys+2) - // - // Use free_o3 at the corners for Dirichlet y-boundaries because we don't know - // what value to pass for the corner - PetscScalar val = 1.0; - int row = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -3.0; - int col = globalIndex(localmesh->xend + 1, localmesh->ystart); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = 3.0; - col = globalIndex(localmesh->xend + 1, localmesh->ystart + 1); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = -1.0; - col = globalIndex(localmesh->xend + 1, localmesh->ystart + 2); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } else { - throw BoutException("Unsupported option for y_bndry"); - } - } - } - if (localmesh->hasBndryUpperY()) { - if (localmesh->firstX()) { - if (y_bndry == "neumann") { - // Neumann y-bc - // f(xs-1,ys-1) = f(xs-1,ys) - PetscScalar val = 1.0; - int row = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -1.0; - int col = globalIndex(localmesh->xstart - 1, localmesh->yend); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } else if (y_bndry == "free_o3" or y_bndry == "dirichlet") { - // 'free_o3' extrapolating boundary condition on Y boundaries - // f(xs-1,ys-1) = 3*f(xs-1,ys) - 3*f(xs-1,ys+1) + f(xs-1,ys+2) - // - // Use free_o3 at the corners for Dirichlet y-boundaries because we don't know - // what value to pass for the corner - PetscScalar val = 1.0; - int row = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -3.0; - int col = globalIndex(localmesh->xstart - 1, localmesh->yend); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = 3.0; - col = globalIndex(localmesh->xstart - 1, localmesh->yend - 1); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = -1.0; - col = globalIndex(localmesh->xstart - 1, localmesh->yend - 2); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } else { - throw BoutException("Unsupported option for y_bndry"); - } - } - if (localmesh->lastX()) { - if (y_bndry == "neumann") { - // Neumann y-bc - // f(xe+1,ys-1) = f(xe+1,ys) - PetscScalar val = 1.0; - int row = globalIndex(localmesh->xend + 1, localmesh->yend + 1); - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -1.0; - int col = globalIndex(localmesh->xend + 1, localmesh->yend); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } else if (y_bndry == "free_o3" or y_bndry == "dirichlet") { - // 'free_o3' extrapolating boundary condition on Y boundaries - // f(xe+1,ys-1) = 3*f(xe+1,ys) - 3*f(xe+1,ys+1) + f(xe+1,ys+2) - // - // Use free_o3 at the corners for Dirichlet y-boundaries because we don't know - // what value to pass for the corner - PetscScalar val = 1.0; - int row = globalIndex(localmesh->xend + 1, localmesh->yend + 1); - MatSetValues(MatA, 1, &row, 1, &row, &val, INSERT_VALUES); - - val = -3.0; - int col = globalIndex(localmesh->xend + 1, localmesh->yend); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = 3.0; - col = globalIndex(localmesh->xend + 1, localmesh->yend - 1); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - - val = -1.0; - col = globalIndex(localmesh->xend + 1, localmesh->yend - 2); - MatSetValues(MatA, 1, &row, 1, &col, &val, INSERT_VALUES); - } else { - throw BoutException("Unsupported option for y_bndry"); - } - } - } - } - - // Assemble Matrix - MatAssemblyBegin(MatA, MAT_FINAL_ASSEMBLY); - MatAssemblyEnd(MatA, MAT_FINAL_ASSEMBLY); - - // Set the operator -#if PETSC_VERSION_GE(3, 5, 0) - KSPSetOperators(ksp, MatA, MatA); -#else - KSPSetOperators(ksp, MatA, MatA, DIFFERENT_NONZERO_PATTERN); -#endif - - // Set coefficients for preconditioner - cr->setCoefs(acoef, bcoef, ccoef); -} - -void LaplaceXY::setMatrixElementsFiniteVolume(const Field2D& A, const Field2D& B) { - ////////////////////////////////////////////////// - // Set Matrix elements - // - // (1/J) d/dx ( J * g11 d/dx ) + (1/J) d/dy ( J * g22 d/dy ) - - auto coords = localmesh->getCoordinates(location); - const Field2D J_DC = DC(coords->J); - const Field2D g11_DC = DC(coords->g11); - const Field2D dx_DC = DC(coords->dx); - const Field2D dy_DC = DC(coords->dy); - const Field2D g_22_DC = DC(coords->g_22); - const Field2D g_23_DC = DC(coords->g_23); - const Field2D g23_DC = DC(coords->g23); - - for (int x = localmesh->xstart; x <= localmesh->xend; x++) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - // stencil entries - PetscScalar c, xm, xp, ym, yp; - - // XX component - - // Metrics on x+1/2 boundary - BoutReal J = 0.5 * (J_DC(x, y) + J_DC(x + 1, y)); - BoutReal g11 = 0.5 * (g11_DC(x, y) + g11_DC(x + 1, y)); - BoutReal dx = 0.5 * (dx_DC(x, y) + dx_DC(x + 1, y)); - BoutReal Acoef = 0.5 * (A(x, y) + A(x + 1, y)); - - BoutReal val = Acoef * J * g11 / (J_DC(x, y) * dx * dx_DC(x, y)); - xp = val; - c = -val; - - // Metrics on x-1/2 boundary - J = 0.5 * (J_DC(x, y) + J_DC(x - 1, y)); - g11 = 0.5 * (g11_DC(x, y) + g11_DC(x - 1, y)); - dx = 0.5 * (dx_DC(x, y) + dx_DC(x - 1, y)); - Acoef = 0.5 * (A(x, y) + A(x - 1, y)); - - val = Acoef * J * g11 / (J_DC(x, y) * dx * dx_DC(x, y)); - xm = val; - c -= val; - - c += B(x, y); - - // Put values into the preconditioner, X derivatives only - acoef(y - localmesh->ystart, x - xstart) = xm; - bcoef(y - localmesh->ystart, x - xstart) = c; - ccoef(y - localmesh->ystart, x - xstart) = xp; - - if (include_y_derivs) { - // YY component - // Metrics at y+1/2 - J = 0.5 * (J_DC(x, y) + J_DC(x, y + 1)); - BoutReal g_22 = 0.5 * (g_22_DC(x, y) + g_22_DC(x, y + 1)); - BoutReal g23 = 0.5 * (g23_DC(x, y) + g23_DC(x, y + 1)); - BoutReal g_23 = 0.5 * (g_23_DC(x, y) + g_23_DC(x, y + 1)); - BoutReal dy = 0.5 * (dy_DC(x, y) + dy_DC(x, y + 1)); - Acoef = 0.5 * (A(x, y + 1) + A(x, y)); - - val = -Acoef * J * g23 * g_23 / (g_22 * J_DC(x, y) * dy * dy_DC(x, y)); - yp = val; - c -= val; - - // Metrics at y-1/2 - J = 0.5 * (J_DC(x, y) + J_DC(x, y - 1)); - g_22 = 0.5 * (g_22_DC(x, y) + g_22_DC(x, y - 1)); - g23 = 0.5 * (g23_DC(x, y) + g23_DC(x, y - 1)); - g_23 = 0.5 * (g_23_DC(x, y) + g_23_DC(x, y - 1)); - dy = 0.5 * (dy_DC(x, y) + dy_DC(x, y - 1)); - Acoef = 0.5 * (A(x, y - 1) + A(x, y)); - - val = -Acoef * J * g23 * g_23 / (g_22 * J_DC(x, y) * dy * dy_DC(x, y)); - ym = val; - c -= val; - } - - ///////////////////////////////////////////////// - // Now have a 5-point stencil for the Laplacian - - int row = globalIndex(x, y); - - // Set the centre (diagonal) - MatSetValues(MatA, 1, &row, 1, &row, &c, INSERT_VALUES); - - // X + 1 - int col = globalIndex(x + 1, y); - MatSetValues(MatA, 1, &row, 1, &col, &xp, INSERT_VALUES); - - // X - 1 - col = globalIndex(x - 1, y); - MatSetValues(MatA, 1, &row, 1, &col, &xm, INSERT_VALUES); - - if (include_y_derivs) { - // Y + 1 - col = globalIndex(x, y + 1); - MatSetValues(MatA, 1, &row, 1, &col, &yp, INSERT_VALUES); - - // Y - 1 - col = globalIndex(x, y - 1); - MatSetValues(MatA, 1, &row, 1, &col, &ym, INSERT_VALUES); - } - } - } -} - -void LaplaceXY::setMatrixElementsFiniteDifference(const Field2D& A, const Field2D& B) { - ////////////////////////////////////////////////// - // Set Matrix elements - // - // Div(A Grad(f)) + B f - // = A Laplace_perp(f) + Grad_perp(A).Grad_perp(f) + B f - // = A*(G1*dfdx + (G2-1/J*d/dy(J/g_22))*dfdy - // + g11*d2fdx2 + (g22-1/g_22)*d2fdy2 + 2*g12*d2fdxdy) - // + g11*dAdx*dfdx + (g22-1/g_22)*dAdy*dfdy + g12*(dAdx*dfdy + dAdy*dfdx) - // + B*f - - auto coords = localmesh->getCoordinates(location); - const Field2D G1_2D = DC(coords->G1); - const Field2D G2_2D = DC(coords->G2); - const Field2D J_2D = DC(coords->J); - const Field2D g11_2D = DC(coords->g11); - const Field2D g_22_2D = DC(coords->g_22); - const Field2D g22_2D = DC(coords->g22); - const Field2D g12_2D = DC(coords->g12); - const Field2D d1_dx_2D = DC(coords->d1_dx); - const Field2D d1_dy_2D = DC(coords->d1_dy); - const Field2D dx_2D = DC(coords->dx); - const Field2D dy_2D = DC(coords->dy); - - const Field2D coef_dfdy = G2_2D - DC(DDY(J_2D / g_22_2D) / J_2D); - - for (int x = localmesh->xstart; x <= localmesh->xend; x++) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - // stencil entries - PetscScalar c, xm, xp, ym, yp, xpyp, xpym, xmyp, xmym; - - BoutReal dx = dx_2D(x, y); - - // A*G1*dfdx - BoutReal val = A(x, y) * G1_2D(x, y) / (2. * dx); - xp = val; - xm = -val; - - // A*g11*d2fdx2 - val = A(x, y) * g11_2D(x, y) / SQ(dx); - xp += val; - c = -2. * val; - xm += val; - // Non-uniform grid correction - val = A(x, y) * g11_2D(x, y) * d1_dx_2D(x, y) / (2. * dx); - xp += val; - xm -= val; - - // g11*dAdx*dfdx - val = g11_2D(x, y) * (A(x + 1, y) - A(x - 1, y)) / (4. * SQ(dx)); - xp += val; - xm -= val; - - // B*f - c += B(x, y); - - // Put values into the preconditioner, X derivatives only - acoef(y - localmesh->ystart, x - xstart) = xm; - bcoef(y - localmesh->ystart, x - xstart) = c; - ccoef(y - localmesh->ystart, x - xstart) = xp; - - if (include_y_derivs) { - BoutReal dy = dy_2D(x, y); - BoutReal dAdx = (A(x + 1, y) - A(x - 1, y)) / (2. * dx); - BoutReal dAdy = (A(x, y + 1) - A(x, y - 1)) / (2. * dy); - - // A*(G2-1/J*d/dy(J/g_22))*dfdy - val = A(x, y) * coef_dfdy(x, y) / (2. * dy); - yp = val; - ym = -val; - - // A*(g22-1/g_22)*d2fdy2 - val = A(x, y) * (g22_2D(x, y) - 1. / g_22_2D(x, y)) / SQ(dy); - yp += val; - c -= 2. * val; - ym += val; - // Non-uniform mesh correction - val = A(x, y) * (g22_2D(x, y) - 1. / g_22_2D(x, y)) * d1_dy_2D(x, y) / (2. * dy); - yp += val; - ym -= val; - - // 2*A*g12*d2dfdxdy - val = A(x, y) * g12_2D(x, y) / (2. * dx * dy); - xpyp = val; - xpym = -val; - xmyp = -val; - xmym = val; - - // g22*dAdy*dfdy - val = (g22_2D(x, y) - 1. / g_22_2D(x, y)) * dAdy / (2. * dy); - yp += val; - ym -= val; - - // g12*(dAdx*dfdy + dAdy*dfdx) - val = g12_2D(x, y) * dAdx / (2. * dy); - yp += val; - ym -= val; - val = g12_2D(x, y) * dAdy / (2. * dx); - xp += val; - xm -= val; - } - - ///////////////////////////////////////////////// - // Now have a 9-point stencil for the Laplacian - - int row = globalIndex(x, y); - - // Set the centre (diagonal) - MatSetValues(MatA, 1, &row, 1, &row, &c, INSERT_VALUES); - - // X + 1 - int col = globalIndex(x + 1, y); - MatSetValues(MatA, 1, &row, 1, &col, &xp, INSERT_VALUES); - - // X - 1 - col = globalIndex(x - 1, y); - MatSetValues(MatA, 1, &row, 1, &col, &xm, INSERT_VALUES); - - if (include_y_derivs) { - // Y + 1 - col = globalIndex(x, y + 1); - MatSetValues(MatA, 1, &row, 1, &col, &yp, INSERT_VALUES); - - // Y - 1 - col = globalIndex(x, y - 1); - MatSetValues(MatA, 1, &row, 1, &col, &ym, INSERT_VALUES); - - // X + 1, Y + 1 - col = globalIndex(x + 1, y + 1); - MatSetValues(MatA, 1, &row, 1, &col, &xpyp, INSERT_VALUES); - - // X + 1, Y - 1 - col = globalIndex(x + 1, y - 1); - MatSetValues(MatA, 1, &row, 1, &col, &xpym, INSERT_VALUES); - - // X - 1, Y + 1 - col = globalIndex(x - 1, y + 1); - MatSetValues(MatA, 1, &row, 1, &col, &xmyp, INSERT_VALUES); - - // X - 1, Y - 1 - col = globalIndex(x - 1, y - 1); - MatSetValues(MatA, 1, &row, 1, &col, &xmym, INSERT_VALUES); - } - } - } -} - -LaplaceXY::~LaplaceXY() { - PetscBool is_finalised; - PetscFinalized(&is_finalised); - - if (!is_finalised) { - // PetscFinalize may already have destroyed this object - KSPDestroy(&ksp); - } - - VecDestroy(&xs); - VecDestroy(&bs); - MatDestroy(&MatA); -} - -const Field2D LaplaceXY::solve(const Field2D& rhs, const Field2D& x0) { - Timer timer("invert"); - - ASSERT1(rhs.getMesh() == localmesh); - ASSERT1(x0.getMesh() == localmesh); - ASSERT1(rhs.getLocation() == location); - ASSERT1(x0.getLocation() == location); - - // Load initial guess x0 into xs and rhs into bs - - for (int x = localmesh->xstart; x <= localmesh->xend; x++) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int ind = globalIndex(x, y); - - PetscScalar val = x0(x, y); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - val = rhs(x, y); - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } - - if (finite_volume) { - solveFiniteVolume(x0); - } else { - solveFiniteDifference(x0); - } - - // Assemble RHS Vector - VecAssemblyBegin(bs); - VecAssemblyEnd(bs); - - // Assemble Trial Solution Vector - VecAssemblyBegin(xs); - VecAssemblyEnd(xs); - - // Solve the system - KSPSolve(ksp, bs, xs); - - KSPConvergedReason reason; - KSPGetConvergedReason(ksp, &reason); - - if (reason <= 0) { - throw BoutException("LaplaceXY failed to converge. Reason {} ({:d})", - KSPConvergedReasons[reason], static_cast(reason)); - } - - if (save_performance) { - // Update performance monitoring information - n_calls++; - - int iterations = 0; - KSPGetIterationNumber(ksp, &iterations); - - average_iterations = BoutReal(n_calls - 1) / BoutReal(n_calls) * average_iterations - + BoutReal(iterations) / BoutReal(n_calls); - } - - ////////////////////////// - // Copy data into result - - Field2D result; - result.allocate(); - result.setLocation(location); - - for (int x = localmesh->xstart; x <= localmesh->xend; x++) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int ind = globalIndex(x, y); - - PetscScalar val; - VecGetValues(xs, 1, &ind, &val); - result(x, y) = val; - } - } - - // Inner X boundary - if (localmesh->firstX()) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int ind = globalIndex(localmesh->xstart - 1, y); - PetscScalar val; - VecGetValues(xs, 1, &ind, &val); - for (int x = localmesh->xstart - 1; x >= 0; x--) { - result(x, y) = val; - } - } - } - - // Outer X boundary - if (localmesh->lastX()) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int ind = globalIndex(localmesh->xend + 1, y); - PetscScalar val; - VecGetValues(xs, 1, &ind, &val); - for (int x = localmesh->xend + 1; x < localmesh->LocalNx; x++) { - result(x, y) = val; - } - } - } - - // Lower Y boundary - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - if ( - // Should not go into corner cells, finite-volume LaplaceXY stencil does not include - // them - (finite_volume and (it.ind < localmesh->xstart or it.ind > localmesh->xend)) - - // Only go into first corner cell for finite-difference - or (it.ind < localmesh->xstart - 1 or it.ind > localmesh->xend + 1)) { - continue; - } - int ind = globalIndex(it.ind, localmesh->ystart - 1); - PetscScalar val; - VecGetValues(xs, 1, &ind, &val); - for (int y = localmesh->ystart - 1; y >= 0; y--) { - result(it.ind, y) = val; - } - } - - // Upper Y boundary - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - if ( - // Should not go into corner cells, finite-volume LaplaceXY stencil does not include - // them - (finite_volume and (it.ind < localmesh->xstart or it.ind > localmesh->xend)) - - // Only go into first corner cell for finite-difference - or (it.ind < localmesh->xstart - 1 or it.ind > localmesh->xend + 1)) { - continue; - } - int ind = globalIndex(it.ind, localmesh->yend + 1); - PetscScalar val; - VecGetValues(xs, 1, &ind, &val); - for (int y = localmesh->yend + 1; y < localmesh->LocalNy; y++) { - result(it.ind, y) = val; - } - } - - return result; -} - -void LaplaceXY::solveFiniteVolume(const Field2D& x0) { - // Use original LaplaceXY implementation of passing boundary values for backward - // compatibility - if (localmesh->firstX()) { - if (x_inner_dirichlet) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int ind = globalIndex(localmesh->xstart - 1, y); - - PetscScalar val = x0(localmesh->xstart - 1, y); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - val = 0.5 * (x0(localmesh->xstart - 1, y) + x0(localmesh->xstart, y)); - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } else { - // Inner X boundary (Neumann) - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int ind = globalIndex(localmesh->xstart - 1, y); - - PetscScalar val = x0(localmesh->xstart - 1, y); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - val = 0.0; // x0(localmesh->xstart-1,y) - x0(localmesh->xstart,y); - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } - } - - // Outer X boundary (Dirichlet) - if (localmesh->lastX()) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int ind = globalIndex(localmesh->xend + 1, y); - - PetscScalar val = x0(localmesh->xend + 1, y); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - val = 0.5 * (x0(localmesh->xend, y) + x0(localmesh->xend + 1, y)); - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } - - if (y_bndry == "dirichlet") { - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int ind = globalIndex(it.ind, localmesh->ystart - 1); - - PetscScalar val = x0(it.ind, localmesh->ystart - 1); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - val = 0.5 * (x0(it.ind, localmesh->ystart - 1) + x0(it.ind, localmesh->ystart)); - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int ind = globalIndex(it.ind, localmesh->yend + 1); - - PetscScalar val = x0(it.ind, localmesh->yend + 1); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - val = 0.5 * (x0(it.ind, localmesh->yend + 1) + x0(it.ind, localmesh->yend)); - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } else if (y_bndry == "neumann" or y_bndry == "free_o3") { - // Y boundaries Neumann - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int ind = globalIndex(it.ind, localmesh->ystart - 1); - - PetscScalar val = x0(it.ind, localmesh->ystart - 1); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int ind = globalIndex(it.ind, localmesh->yend + 1); - - PetscScalar val = x0(it.ind, localmesh->yend + 1); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } else { - throw BoutException("Unsupported option for y_bndry"); - } -} - -void LaplaceXY::solveFiniteDifference(const Field2D& x0) { - // For finite-difference implementation pass boundary values in the same way as for - // the 'Laplacian' solvers - the value to use (for Dirichlet boundary conditions) on - // the boundary (which is half way between grid cell and boundary cell) is passed as - // the value in the first boundary cell. - if (localmesh->firstX()) { - if (x_inner_dirichlet) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int ind = globalIndex(localmesh->xstart - 1, y); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 2. * x0(localmesh->xstart - 1, y) - x0(localmesh->xstart, y); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Pass the value from boundary cell of x0 as the boundary condition to the rhs - val = x0(localmesh->xstart - 1, y); - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } else { - // Inner X boundary (Neumann) - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int ind = globalIndex(localmesh->xstart - 1, y); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = x0(localmesh->xstart, y); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } - } - - // Outer X boundary (Dirichlet) - if (localmesh->lastX()) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - int ind = globalIndex(localmesh->xend + 1, y); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 2. * x0(localmesh->xend + 1, y) - x0(localmesh->xend, y); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Pass the value from boundary cell of x0 as the boundary condition to the rhs - val = x0(localmesh->xend + 1, y); - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } - - if (y_bndry == "dirichlet") { - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, they are treated specially below - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int ind = globalIndex(it.ind, localmesh->ystart - 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = - 2. * x0(it.ind, localmesh->ystart - 1) - x0(it.ind, localmesh->ystart); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Pass the value from boundary cell of x0 as the boundary condition to the rhs - val = x0(it.ind, localmesh->ystart - 1); - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, they are treated specially below - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int ind = globalIndex(it.ind, localmesh->yend + 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = - 2. * x0(it.ind, localmesh->yend + 1) - x0(it.ind, localmesh->yend); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Pass the value from boundary cell of x0 as the boundary condition to the rhs - val = x0(it.ind, localmesh->yend + 1); - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - - // Use free_o3 for the corner boundary cells - if (localmesh->hasBndryLowerY()) { - if (localmesh->firstX()) { - int ind = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 3. * x0(localmesh->xstart - 1, localmesh->ystart) - - 3. * x0(localmesh->xstart - 1, localmesh->ystart + 1) - + x0(localmesh->xstart - 1, localmesh->ystart + 2); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - if (localmesh->lastX()) { - int ind = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 3. * x0(localmesh->xend + 1, localmesh->ystart) - - 3. * x0(localmesh->xend + 1, localmesh->ystart + 1) - + x0(localmesh->xend + 1, localmesh->ystart + 2); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } - if (localmesh->hasBndryUpperY()) { - if (localmesh->firstX()) { - int ind = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 3. * x0(localmesh->xstart - 1, localmesh->yend) - - 3. * x0(localmesh->xstart - 1, localmesh->yend - 1) - + x0(localmesh->xstart - 1, localmesh->yend - 2); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - if (localmesh->lastX()) { - int ind = globalIndex(localmesh->xend + 1, localmesh->yend + 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 3. * x0(localmesh->xend + 1, localmesh->yend) - - 3. * x0(localmesh->xend + 1, localmesh->yend - 1) - + x0(localmesh->xend + 1, localmesh->yend - 2); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } - } else if (y_bndry == "neumann") { - // Y boundaries Neumann - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, they are treated specially below - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int ind = globalIndex(it.ind, localmesh->ystart - 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = x0(it.ind, localmesh->ystart); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - if (localmesh->hasBndryLowerY()) { - if (localmesh->firstX()) { - int ind = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = x0(localmesh->xstart - 1, localmesh->ystart); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - if (localmesh->lastX()) { - int ind = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = x0(localmesh->xend + 1, localmesh->ystart); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } - - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, they are treated specially below - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int ind = globalIndex(it.ind, localmesh->yend + 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = x0(it.ind, localmesh->yend); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - if (localmesh->hasBndryUpperY()) { - if (localmesh->firstX()) { - int ind = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = x0(localmesh->xstart - 1, localmesh->yend); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - if (localmesh->lastX()) { - int ind = globalIndex(localmesh->xend + 1, localmesh->yend + 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = x0(localmesh->xend + 1, localmesh->yend); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } - } else if (y_bndry == "free_o3") { - // Y boundaries free_o3 - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, they are treated specially below - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int ind = globalIndex(it.ind, localmesh->ystart - 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 3. * x0(it.ind, localmesh->ystart) - - 3. * x0(it.ind, localmesh->ystart + 1) - + x0(it.ind, localmesh->ystart + 2); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - if (localmesh->hasBndryLowerY()) { - if (localmesh->firstX()) { - int ind = globalIndex(localmesh->xstart - 1, localmesh->ystart - 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 3. * x0(localmesh->xstart - 1, localmesh->ystart) - - 3. * x0(localmesh->xstart - 1, localmesh->ystart + 1) - + x0(localmesh->xstart - 1, localmesh->ystart + 2); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - if (localmesh->lastX()) { - int ind = globalIndex(localmesh->xend + 1, localmesh->ystart - 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 3. * x0(localmesh->xend + 1, localmesh->ystart) - - 3. * x0(localmesh->xend + 1, localmesh->ystart + 1) - + x0(localmesh->xend + 1, localmesh->ystart + 2); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } - - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, they are treated specially below - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - int ind = globalIndex(it.ind, localmesh->yend + 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 3. * x0(it.ind, localmesh->yend) - - 3. * x0(it.ind, localmesh->yend - 1) - + x0(it.ind, localmesh->yend - 2); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - if (localmesh->hasBndryUpperY()) { - if (localmesh->firstX()) { - int ind = globalIndex(localmesh->xstart - 1, localmesh->yend + 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 3. * x0(localmesh->xstart - 1, localmesh->yend) - - 3. * x0(localmesh->xstart - 1, localmesh->yend - 1) - + x0(localmesh->xstart - 1, localmesh->yend - 2); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - if (localmesh->lastX()) { - int ind = globalIndex(localmesh->xend + 1, localmesh->yend + 1); - - // For the boundary value of the initial guess, use the value that would be set by - // applying the boundary condition to the initial guess - PetscScalar val = 3. * x0(localmesh->xend + 1, localmesh->yend) - - 3. * x0(localmesh->xend + 1, localmesh->yend - 1) - + x0(localmesh->xend + 1, localmesh->yend - 2); - VecSetValues(xs, 1, &ind, &val, INSERT_VALUES); - - // Set the value for the rhs of the boundary condition to zero - val = 0.0; - VecSetValues(bs, 1, &ind, &val, INSERT_VALUES); - } - } - } else { - throw BoutException("Unsupported option for y_bndry"); - } -} - -/*! Preconditioner - * NOTE: For generality, this routine does use globalIndex() in the inner loop, although - * this may be slightly less efficient than incrementing an integer for the global index, - * the finite-volume and finite-difference implementations have slightly different - * indexing patterns, so incrementing an integer would be tricky. - */ -int LaplaceXY::precon(Vec input, Vec result) { - - for (auto itdwn = localmesh->iterateBndryLowerY(); !itdwn.isDone(); itdwn++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (itdwn.ind < localmesh->xstart or itdwn.ind > localmesh->xend) { - continue; - } - const int ind = globalIndex(itdwn.ind, localmesh->ystart - 1); - PetscScalar val; - VecGetValues(input, 1, &ind, &val); - VecSetValues(result, 1, &ind, &val, INSERT_VALUES); - } - for (auto itup = localmesh->iterateBndryUpperY(); !itup.isDone(); itup++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (itup.ind < localmesh->xstart or itup.ind > localmesh->xend) { - continue; - } - const int ind = globalIndex(itup.ind, localmesh->yend + 1); - PetscScalar val; - VecGetValues(input, 1, &ind, &val); - VecSetValues(result, 1, &ind, &val, INSERT_VALUES); - } - - // Load vector x into bvals array - for (int x = xstart; x <= xend; x++) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - const int ind = globalIndex(x, y); - PetscScalar val; - VecGetValues(input, 1, &ind, &val); - bvals(y - localmesh->ystart, x - xstart) = val; - } - } - - // Solve tridiagonal systems using CR solver - cr->solve(bvals, xvals); - - // Save result xvals into y array - for (int x = xstart; x <= xend; x++) { - for (int y = localmesh->ystart; y <= localmesh->yend; y++) { - const int ind = globalIndex(x, y); - PetscScalar val = xvals(y - localmesh->ystart, x - xstart); - VecSetValues(result, 1, &ind, &val, INSERT_VALUES); - } - } - VecAssemblyBegin(result); - VecAssemblyEnd(result); - return 0; -} - -/////////////////////////////////////////////////////////////// - -int LaplaceXY::localSize() { - - // Bulk of points - const int nx = localmesh->xend - localmesh->xstart + 1; - const int ny = localmesh->yend - localmesh->ystart + 1; - - int n = nx * ny; - - // X boundaries - if (localmesh->firstX()) { - n += ny; - } - if (localmesh->lastX()) { - n += ny; - } - - // Y boundaries - for (RangeIterator it = localmesh->iterateBndryLowerY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - n++; - } - if ((not finite_volume) and localmesh->hasBndryLowerY()) { - if (localmesh->firstX()) { - n++; - } - if (localmesh->lastX()) { - n++; - } - } - for (RangeIterator it = localmesh->iterateBndryUpperY(); !it.isDone(); it++) { - // Should not go into corner cells, LaplaceXY stencil does not include them - if (it.ind < localmesh->xstart or it.ind > localmesh->xend) { - continue; - } - n++; - } - if ((not finite_volume) and localmesh->hasBndryUpperY()) { - if (localmesh->firstX()) { - n++; - } - if (localmesh->lastX()) { - n++; - } - } - - return n; -} - -int LaplaceXY::globalIndex(int x, int y) { - if ((x < 0) || (x >= localmesh->LocalNx) || (y < 0) || (y >= localmesh->LocalNy)) { - return -1; // Out of range - } - - // Get the index from a Field2D, round to integer - return static_cast(std::round(indexXY(x, y))); -} - -void LaplaceXY::savePerformance(Solver& solver, const std::string& name) { - // set flag so that performance monitoring values are calculated - save_performance = true; - - // add values to be saved to the output - if (not name.empty()) { - default_prefix = name; - } - - // add monitor to reset counters/averages for new output timestep - // monitor added to back of queue, so that values are reset after being saved - solver.addMonitor(&monitor, Solver::BACK); -} - -int LaplaceXY::LaplaceXYMonitor::call(Solver* /*solver*/, BoutReal /*time*/, int /*iter*/, - int /*nout*/) { - laplacexy.output_average_iterations = laplacexy.average_iterations; - - laplacexy.n_calls = 0; - laplacexy.average_iterations = 0.; - - return 0; -} - -void LaplaceXY::LaplaceXYMonitor::outputVars(Options& output_options, - const std::string& time_dimension) { - output_options[fmt::format("{}_average_iterations", laplacexy.default_prefix)] - .assignRepeat(laplacexy.output_average_iterations, time_dimension); -} - -#endif // BOUT_HAS_PETSC +// DO NOT REMOVE: ensures linker keeps all symbols in this TU +void LaplaceXYFactory::ensureRegistered() {} diff --git a/src/mesh/boundary_factory.cxx b/src/mesh/boundary_factory.cxx index d112a216ad..5934daff31 100644 --- a/src/mesh/boundary_factory.cxx +++ b/src/mesh/boundary_factory.cxx @@ -228,46 +228,82 @@ BoundaryOpBase* BoundaryFactory::createFromOptions(const string& varname, string prefix("bndry_"); - string side; + std::array sides; + sides[0] = region->label; switch (region->location) { case BNDRY_XIN: { - side = "xin"; + sides[1] = "xin"; break; } case BNDRY_XOUT: { - side = "xout"; + sides[1] = "xout"; break; } case BNDRY_YDOWN: { - side = "ydown"; + sides[1] = "ydown"; break; } case BNDRY_YUP: { - side = "yup"; + sides[1] = "yup"; break; } case BNDRY_PAR_FWD_XIN: { - side = "par_yup_xin"; + sides[1] = "par_yup_xin"; break; } case BNDRY_PAR_FWD_XOUT: { - side = "par_yup_xout"; + sides[1] = "par_yup_xout"; break; } case BNDRY_PAR_BKWD_XIN: { - side = "par_ydown_xin"; + sides[1] = "par_ydown_xin"; break; } case BNDRY_PAR_BKWD_XOUT: { - side = "par_ydown_xout"; + sides[1] = "par_ydown_xout"; break; } default: { - side = "all"; + sides[1] = "all"; break; } } + switch (region->location) { + case BNDRY_PAR_FWD_XIN: + case BNDRY_PAR_BKWD_XIN: { + sides[2] = "par_xin"; + break; + } + case BNDRY_PAR_BKWD_XOUT: + case BNDRY_PAR_FWD_XOUT: { + sides[2] = "par_xout"; + break; + } + default: { + sides[2] = "all"; + break; + } + } + switch (region->location) { + case BNDRY_PAR_FWD_XIN: + case BNDRY_PAR_FWD_XOUT: { + sides[3] = "par_yup"; + break; + } + case BNDRY_PAR_BKWD_XIN: + case BNDRY_PAR_BKWD_XOUT: { + sides[3] = "par_ydown"; + break; + } + default: { + sides[3] = "all"; + break; + } + } + + sides[4] = region->isParallel ? "par_all" : "all"; + // Get options Options* options = Options::getRoot(); @@ -275,27 +311,10 @@ BoundaryOpBase* BoundaryFactory::createFromOptions(const string& varname, Options* varOpts = options->getSection(varname); string set; - /// First try looking for (var, region) - if (varOpts->isSet(prefix + region->label)) { - varOpts->get(prefix + region->label, set, ""); - return create(set, region); - } - - /// Then (var, side) - if (varOpts->isSet(prefix + side)) { - varOpts->get(prefix + side, set, ""); - return create(set, region); - } - - /// Then (var, all) - if (region->isParallel) { - if (varOpts->isSet(prefix + "par_all")) { - varOpts->get(prefix + "par_all", set, ""); - return create(set, region); - } - } else { - if (varOpts->isSet(prefix + "all")) { - varOpts->get(prefix + "all", set, ""); + /// First try looking for (var, ...) + for (const auto& side : sides) { + if (varOpts->isSet(prefix + side)) { + varOpts->get(prefix + side, set, ""); return create(set, region); } } @@ -303,16 +322,13 @@ BoundaryOpBase* BoundaryFactory::createFromOptions(const string& varname, // Get the "all" options varOpts = options->getSection("all"); - /// Then (all, region) - if (varOpts->isSet(prefix + region->label)) { - varOpts->get(prefix + region->label, set, ""); - return create(set, region); - } - - /// Then (all, side) - if (varOpts->isSet(prefix + side)) { - varOpts->get(prefix + side, set, ""); - return create(set, region); + /// First try looking for (all, ...) + for (const auto& side : sides) { + if (varOpts->isSet(prefix + side)) { + varOpts->get(prefix + side, set, + region->isParallel ? "parallel_dirichlet_o2" : "dirichlet"); + return create(set, region); + } } /// Then (all, all) diff --git a/src/mesh/coordinates.cxx b/src/mesh/coordinates.cxx index d013634644..24bf2de0ba 100644 --- a/src/mesh/coordinates.cxx +++ b/src/mesh/coordinates.cxx @@ -606,6 +606,29 @@ Coordinates::Coordinates(Mesh* mesh, Options* options) // Allow transform to fix things up transform->loadParallelMetrics(this); + + if (Bxy.isFci()) { + BoutReal maxError = 0; + auto BJg = Bxy.asField3DParallel() * J / sqrt(g_22); + for (int p = -mesh->ystart; p <= mesh->ystart; p++) { + if (p == 0) { + continue; + } + BOUT_FOR(i, BJg.getRegion("RGN_NO_BNDRY")) { + auto local = BJg[i] / BJg.ynext(p)[i.yp(p)]; + maxError = std::max(std::abs(local - 1), maxError); + } + } + BoutReal allowedError = (*options)["allowedFluxError"].withDefault(1e-6); + if (maxError < allowedError / 100) { + output_info.write("\tInfo: The maximum flux conservation error is {:e}", maxError); + } else if (maxError < allowedError) { + output_warn.write("\tWarning: The maximum flux conservation error is {:e}", + maxError); + } else { + throw BoutException("Error: The maximum flux conservation error is {:e}", maxError); + } + } } Coordinates::Coordinates(Mesh* mesh, Options* options, const CELL_LOC loc, @@ -1039,15 +1062,9 @@ int Coordinates::geometry(bool recalculate_staggered, G3_23 = 0.5 * g13 * (DDZ(g_12) + DDY(g_13) - DDX(g_23)) + 0.5 * g23 * DDZ(g_22) + 0.5 * g33 * DDY(g_33); - auto tmp = J * g12; - communicate(tmp); - G1 = (DDX(J * g11) + DDY(tmp) + DDZ(J * g13)) / J; - tmp = J * g22; - communicate(tmp); - G2 = (DDX(J * g12) + DDY(tmp) + DDZ(J * g23)) / J; - tmp = J * g23; - communicate(tmp); - G3 = (DDX(J * g13) + DDY(tmp) + DDZ(J * g33)) / J; + G1 = (DDX(J * g11) + DDY(J.asField3DParallel() * g12) + DDZ(J * g13)) / J; + G2 = (DDX(J * g12) + DDY(J.asField3DParallel() * g22) + DDZ(J * g23)) / J; + G3 = (DDX(J * g13) + DDY(J.asField3DParallel() * g23) + DDZ(J * g33)) / J; // Communicate christoffel symbol terms output_progress.write("\tCommunicating connection terms\n"); @@ -1125,7 +1142,7 @@ int Coordinates::geometry(bool recalculate_staggered, if (localmesh->get(d2y, "d2y" + suffix, 0.0, false, location)) { output_warn.write( "\tWARNING: differencing quantity 'd2y' not found. Calculating from dy\n"); - d1_dy = DDY(1. / dy); // d/di(1/dy) + d1_dy = DDY(1. / dy.asField3DParallel()); // d/di(1/dy) communicate(d1_dy); d1_dy = @@ -1510,8 +1527,8 @@ Coordinates::FieldMetric Coordinates::DDY(const Field2D& f, CELL_LOC loc, return bout::derivatives::index::DDY(f, loc, method, region) / dy; } -Field3D Coordinates::DDY(const Field3D& f, CELL_LOC outloc, const std::string& method, - const std::string& region) const { +Field3D Coordinates::DDY(const Field3DParallel& f, CELL_LOC outloc, + const std::string& method, const std::string& region) const { return bout::derivatives::index::DDY(f, outloc, method, region) / dy; }; @@ -1543,7 +1560,7 @@ Coordinates::FieldMetric Coordinates::Grad_par(const Field2D& var, return DDY(var) * invSg(); } -Field3D Coordinates::Grad_par(const Field3D& var, CELL_LOC outloc, +Field3D Coordinates::Grad_par(const Field3DParallel& var, CELL_LOC outloc, const std::string& method) { TRACE("Coordinates::Grad_par( Field3D )"); ASSERT1(location == outloc || outloc == CELL_DEFAULT); @@ -1563,8 +1580,8 @@ Coordinates::FieldMetric Coordinates::Vpar_Grad_par(const Field2D& v, const Fiel return VDDY(v, f) * invSg(); } -Field3D Coordinates::Vpar_Grad_par(const Field3D& v, const Field3D& f, CELL_LOC outloc, - const std::string& method) { +Field3D Coordinates::Vpar_Grad_par(const Field3D& v, const Field3DParallel& f, + CELL_LOC outloc, const std::string& method) { ASSERT1(location == outloc || outloc == CELL_DEFAULT); return VDDY(v, f, outloc, method) * invSg(); @@ -1585,14 +1602,14 @@ Coordinates::FieldMetric Coordinates::Div_par(const Field2D& f, CELL_LOC outloc, return Bxy * Grad_par(f / Bxy_floc, outloc, method); } -Field3D Coordinates::Div_par(const Field3D& f, CELL_LOC outloc, +Field3D Coordinates::Div_par(const Field3DParallel& f, CELL_LOC outloc, const std::string& method) { TRACE("Coordinates::Div_par( Field3D )"); ASSERT1(location == outloc || outloc == CELL_DEFAULT); // Need Bxy at location of f, which might be different from location of this // Coordinates object - auto Bxy_floc = f.getCoordinates()->Bxy; + const auto& Bxy_floc = f.getCoordinates()->Bxy; if (!f.hasParallelSlices()) { // No yup/ydown fields. The Grad_par operator will @@ -1602,14 +1619,8 @@ Field3D Coordinates::Div_par(const Field3D& f, CELL_LOC outloc, auto coords = f.getCoordinates(); // Need to modify yup and ydown fields - Field3D f_B = f / coords->J * sqrt(coords->g_22); - f_B.splitParallelSlices(); - for (int i = 0; i < f.getMesh()->ystart; ++i) { - f_B.yup(i) = f.yup(i) / coords->J.yup(i) * sqrt(coords->g_22.yup(i)); - f_B.ydown(i) = f.ydown(i) / coords->J.ydown(i) * sqrt(coords->g_22.ydown(i)); - } - return setName(coords->J / sqrt(coords->g_22) * Grad_par(f_B, outloc, method), - "Div_par({:s})", f.name); + Field3D Jg = coords->J / sqrt(coords->g_22.asField3DParallel()); + return setName(Jg * Grad_par(f / Jg, outloc, method), "Div_par({:s})", f.name); } ///////////////////////////////////////////////////////// @@ -1627,7 +1638,7 @@ Coordinates::FieldMetric Coordinates::Grad2_par2(const Field2D& f, CELL_LOC outl return result; } -Field3D Coordinates::Grad2_par2(const Field3D& f, CELL_LOC outloc, +Field3D Coordinates::Grad2_par2(const Field3DParallel& f, CELL_LOC outloc, const std::string& method) { TRACE("Coordinates::Grad2_par2( Field3D )"); if (outloc == CELL_DEFAULT) { @@ -1795,9 +1806,10 @@ Coordinates::FieldMetric Coordinates::Laplace_par(const Field2D& f, CELL_LOC out return D2DY2(f, outloc) / g_22 + DDY(J / g_22, outloc) * DDY(f, outloc) / J; } -Field3D Coordinates::Laplace_par(const Field3D& f, CELL_LOC outloc) { +Field3D Coordinates::Laplace_par(const Field3DParallel& f, CELL_LOC outloc) { ASSERT1(location == outloc || outloc == CELL_DEFAULT); - return D2DY2(f, outloc) / g_22 + DDY(J / g_22, outloc) * ::DDY(f, outloc) / J; + return D2DY2(f, outloc) / g_22 + + DDY(J.asField3DParallel() / g_22, outloc) * ::DDY(f, outloc) / J; } // Full Laplacian operator on scalar field @@ -1817,7 +1829,7 @@ Coordinates::FieldMetric Coordinates::Laplace(const Field2D& f, CELL_LOC outloc, return result; } -Field3D Coordinates::Laplace(const Field3D& f, CELL_LOC outloc, +Field3D Coordinates::Laplace(const Field3DParallel& f, CELL_LOC outloc, const std::string& dfdy_boundary_conditions, const std::string& dfdy_dy_region) { TRACE("Coordinates::Laplace( Field3D )"); diff --git a/src/mesh/interpolation/hermite_spline_xz.cxx b/src/mesh/interpolation/hermite_spline_xz.cxx index 03a062df42..103680c0b8 100644 --- a/src/mesh/interpolation/hermite_spline_xz.cxx +++ b/src/mesh/interpolation/hermite_spline_xz.cxx @@ -165,7 +165,7 @@ void XZHermiteSplineBase::calcWeights(const Field3D& delta_x, const int ny = localmesh->LocalNy; const int nz = localmesh->LocalNz; - const int xend = (localmesh->xend - localmesh->xstart + 1) * localmesh->getNXPE() + const int xend = ((localmesh->xend - localmesh->xstart + 1) * localmesh->getNXPE()) + localmesh->xstart - 1; #ifdef HS_USE_PETSC IndConverter conv{localmesh}; @@ -187,7 +187,19 @@ void XZHermiteSplineBase::calcWeights(const Field3D& delta_x, BoutReal t_x = delta_x(x, y, z) - static_cast(i_corn); BoutReal t_z = delta_z(x, y, z) - static_cast(k_corner(x, y, z)); - // NOTE: A (small) hack to avoid one-sided differences + // NOTE: A (small) hack to avoid one-sided differences. We need at + // least 2 interior points due to an awkwardness with the + // boundaries. The splines need derivatives in x, but we don't + // know the value in the boundaries, so _any_ interpolation in the + // last interior cell can't be done. Instead, we fudge the + // interpolation in the last cell to be at the extreme right-hand + // edge of the previous cell (that is, exactly on the last + // interior point). However, this doesn't work with only one + // interior point, because we have to do something similar to the + // _first_ cell, and these two fudges cancel out and we end up + // indexing into the boundary anyway. + // TODO(peter): Can we remove this if we apply (dirichlet?) BCs to + // the X derivatives? Note that we need at least _2_ if (i_corn >= xend) { i_corn = xend - 1; t_x = 1.0; @@ -386,6 +398,8 @@ Field3D XZHermiteSplineBase::interpolate(const Field3D& f, gf = gf3daccess->communicate_asPtr(f); } + // TODO(peter): Should we apply dirichlet BCs to derivatives? + #if USE_NEW_WEIGHTS and defined(HS_USE_PETSC) BoutReal* ptr; const BoutReal* cptr; diff --git a/src/mesh/parallel/fci.cxx b/src/mesh/parallel/fci.cxx index 580897f47a..3f3e7b0ebf 100644 --- a/src/mesh/parallel/fci.cxx +++ b/src/mesh/parallel/fci.cxx @@ -37,28 +37,57 @@ **************************************************************************/ #include "fci.hxx" + +#include "bout/assert.hxx" +#include "bout/bout_types.hxx" +#include "bout/boutexception.hxx" +#include "bout/field2d.hxx" +#include "bout/field3d.hxx" +#include "bout/field_data.hxx" +#include "bout/mesh.hxx" +#include "bout/msg_stack.hxx" +#include "bout/options.hxx" #include "bout/parallel_boundary_op.hxx" #include "bout/parallel_boundary_region.hxx" -#include -#include -#include -#include -#include +#include "bout/paralleltransform.hxx" +#include "bout/region.hxx" + +#include +#include +#include +#include +#include +#include #include +#include namespace { +using namespace std::literals; // Get a unique name for a field based on the sign/magnitude of the offset std::string parallel_slice_field_name(std::string field, int offset) { - const std::string direction = (offset > 0) ? "forward" : "backward"; + const auto direction = (offset > 0) ? "forward"sv : "backward"sv; // We only have a suffix for parallel slices beyond the first // This is for backwards compatibility - const std::string slice_suffix = - (std::abs(offset) > 1) ? "_" + std::to_string(std::abs(offset)) : ""; - return direction + "_" + field + slice_suffix; + const auto slice_suffix = + (std::abs(offset) > 1) ? fmt::format("_{}", std::abs(offset)) : ""; + return fmt::format("{}_{}{}", direction, field, slice_suffix); }; #if BOUT_USE_METRIC_3D +void set_parallel_metric_component(std::string name, Field3D& component, int offset, + Field3D& data) { + if (!component.hasParallelSlices()) { + component.splitParallelSlices(); + component.allowCalcParallelSlices = false; + } + auto& pcom = component.ynext(offset); + pcom.allocate(); + pcom.setRegion(fmt::format("RGN_YPAR_{:+d}", offset)); + pcom.name = name; + BOUT_FOR(i, component.getRegion("RGN_NOBNDRY")) { pcom[i.yp(offset)] = data[i]; } +} + bool load_parallel_metric_component(std::string name, Field3D& component, int offset, bool doZero) { Mesh* mesh = component.getMesh(); @@ -90,15 +119,7 @@ bool load_parallel_metric_component(std::string name, Field3D& component, int of } tmp = lmin; } - if (!component.hasParallelSlices()) { - component.splitParallelSlices(); - component.allowCalcParallelSlices = false; - } - auto& pcom = component.ynext(offset); - pcom.allocate(); - pcom.setRegion(fmt::format("RGN_YPAR_{:+d}", offset)); - pcom.name = name; - BOUT_FOR(i, component.getRegion("RGN_NOBNDRY")) { pcom[i.yp(offset)] = tmp[i]; } + set_parallel_metric_component(name, component, offset, tmp); return isValid; } #endif @@ -122,6 +143,8 @@ void load_parallel_metric_components([[maybe_unused]] Coordinates* coords, LOAD_PAR(g_13, false); LOAD_PAR(g_23, false); + LOAD_PAR(dy, false); + if (not LOAD_PAR(J, true)) { auto g = coords->g11.ynext(offset) * coords->g22.ynext(offset) * coords->g33.ynext(offset) @@ -141,6 +164,18 @@ void load_parallel_metric_components([[maybe_unused]] Coordinates* coords, auto& pcom = coords->J.ynext(offset); BOUT_FOR(i, J.getRegion(rgn)) { pcom[i] = J[i]; } } + if (coords->Bxy.getMesh()->sourceHasVar(parallel_slice_field_name("Bxy", 1))) { + LOAD_PAR(Bxy, true); + } else { + Field3D tmp{coords->Bxy.getMesh()}; + tmp.allocate(); + BOUT_FOR(iyp, coords->Bxy.getRegion("RGN_NOBNDRY")) { + const auto i = iyp.ym(offset); + tmp[i] = coords->Bxy[i] * coords->g_22[i] / coords->J[i] + * coords->J.ynext(offset)[iyp] / coords->g_22.ynext(offset)[iyp]; + } + set_parallel_metric_component("Bxy", coords->Bxy, offset, tmp); + } #undef LOAD_PAR #endif } @@ -152,64 +187,69 @@ int sgn(T val) { } // namespace -FCIMap::FCIMap(Mesh& mesh, const Coordinates::FieldMetric& UNUSED(dy), Options& options, - int offset_, const std::shared_ptr& inner_boundary, +using namespace std::string_view_literals; + +FCIMap::FCIMap(Mesh& mesh, [[maybe_unused]] const Coordinates::FieldMetric& 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")), + : 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); + TRACE("Creating FCIMAP for direction {:d}", offset_); - if (offset == 0) { + if (offset_ == 0) { throw BoutException( "FCIMap called with offset = 0; You probably didn't mean to do that"); } auto& interpolation_options = options["xzinterpolation"]; - interp = - XZInterpolationFactory::getInstance().create(&interpolation_options, &map_mesh); - interp->setYOffset(offset); + interp = XZInterpolationFactory::getInstance().create(&interpolation_options, map_mesh); + interp->setYOffset(offset_); interp_corner = - XZInterpolationFactory::getInstance().create(&interpolation_options, &map_mesh); - interp_corner->setYOffset(offset); + XZInterpolationFactory::getInstance().create(&interpolation_options, map_mesh); + interp_corner->setYOffset(offset_); // Index-space coordinates of forward/backward points - Field3D xt_prime{&map_mesh}, zt_prime{&map_mesh}; + Field3D xt_prime{map_mesh}; + Field3D zt_prime{map_mesh}; // Real-space coordinates of grid points - Field3D R{&map_mesh}, Z{&map_mesh}; + Field3D R{map_mesh}; + Field3D Z{map_mesh}; // Real-space coordinates of forward/backward points - Field3D R_prime{&map_mesh}, Z_prime{&map_mesh}; + Field3D R_prime{map_mesh}; + Field3D Z_prime{map_mesh}; - map_mesh.get(R, "R", 0.0, false); - map_mesh.get(Z, "Z", 0.0, false); + map_mesh->get(R, "R", 0.0, false); + map_mesh->get(Z, "Z", 0.0, false); // If we can't read in any of these fields, things will silently not // work, so best throw - if (map_mesh.get(xt_prime, parallel_slice_field_name("xt_prime", offset), 0.0, false) + if (map_mesh->get(xt_prime, parallel_slice_field_name("xt_prime", offset_), 0.0, false) != 0) { throw BoutException("Could not read {:s} from grid file!\n" " Either add it to the grid file, or reduce MYG", - parallel_slice_field_name("xt_prime", offset)); + parallel_slice_field_name("xt_prime", offset_)); } - if (map_mesh.get(zt_prime, parallel_slice_field_name("zt_prime", offset), 0.0, false) + if (map_mesh->get(zt_prime, parallel_slice_field_name("zt_prime", offset_), 0.0, false) != 0) { throw BoutException("Could not read {:s} from grid file!\n" " Either add it to the grid file, or reduce MYG", - parallel_slice_field_name("zt_prime", offset)); + parallel_slice_field_name("zt_prime", offset_)); } - if (map_mesh.get(R_prime, parallel_slice_field_name("R", offset), 0.0, false) != 0) { + if (map_mesh->get(R_prime, parallel_slice_field_name("R", offset_), 0.0, false) != 0) { throw BoutException("Could not read {:s} from grid file!\n" " Either add it to the grid file, or reduce MYG", - parallel_slice_field_name("R", offset)); + parallel_slice_field_name("R", offset_)); } - if (map_mesh.get(Z_prime, parallel_slice_field_name("Z", offset), 0.0, false) != 0) { + if (map_mesh->get(Z_prime, parallel_slice_field_name("Z", offset_), 0.0, false) != 0) { throw BoutException("Could not read {:s} from grid file!\n" " Either add it to the grid file, or reduce MYG", - parallel_slice_field_name("Z", offset)); + parallel_slice_field_name("Z", offset_)); } // Cell corners @@ -254,27 +294,28 @@ FCIMap::FCIMap(Mesh& mesh, const Coordinates::FieldMetric& UNUSED(dy), Options& interp->calcWeights(xt_prime, zt_prime); } - const int ncz = map_mesh.LocalNz; + const int ncz = map_mesh->LocalNz; BoutMask to_remove(map_mesh); - const int xend = - map_mesh.xstart + (map_mesh.xend - map_mesh.xstart + 1) * map_mesh.getNXPE() - 1; + const int xend = map_mesh->xstart + + (map_mesh->xend - map_mesh->xstart + 1) * map_mesh->getNXPE() - 1; // Default to the maximum number of points - const int defValid{map_mesh.ystart - 1 + std::abs(offset)}; + const int defValid{map_mesh->ystart - 1 + std::abs(offset)}; // Serial loop because call to BoundaryRegionPar::addPoint // (probably?) can't be done in parallel BOUT_FOR_SERIAL(i, xt_prime.getRegion("RGN_NOBNDRY")) { // z is periodic, so make sure the z-index wraps around if (zperiodic) { - zt_prime[i] = zt_prime[i] - - ncz * (static_cast(zt_prime[i] / static_cast(ncz))); + zt_prime[i] = + zt_prime[i] + - (ncz * (static_cast(zt_prime[i] / static_cast(ncz)))); if (zt_prime[i] < 0.0) { zt_prime[i] += ncz; } } - if ((xt_prime[i] >= map_mesh.xstart) and (xt_prime[i] <= xend)) { + if ((xt_prime[i] >= map_mesh->xstart) and (xt_prime[i] <= xend)) { // Not a boundary continue; } @@ -314,7 +355,7 @@ FCIMap::FCIMap(Mesh& mesh, const Coordinates::FieldMetric& UNUSED(dy), Options& 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 + const BoutReal det = (dR_dx * dZ_dz) - (dR_dz * dZ_dx); // Determinant of 2x2 matrix const BoutReal dR = R_prime[i] - R[i]; const BoutReal dZ = Z_prime[i] - Z[i]; @@ -327,26 +368,27 @@ FCIMap::FCIMap(Mesh& mesh, const Coordinates::FieldMetric& UNUSED(dy), Options& // 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; + ASSERT2(map_mesh->xend - map_mesh->xstart >= 2); + auto boundary = (xt_prime[i] < map_mesh->xstart) ? inner_boundary : outer_boundary; if (!boundary->contains(x, y, z)) { boundary->add_point(x, y, z, x + dx, y + offset - sgn(offset) * 0.5, z + dz, // Intersection point in local index space - std::abs(offset) - 0.5, // Distance to intersection - defValid, offset); + std::abs(offset_) - 0.5, // Distance to intersection + defValid, offset_); } } region_no_boundary = region_no_boundary.mask(to_remove); interp->setRegion(region_no_boundary); - const auto region = fmt::format("RGN_YPAR_{:+d}", offset); - if (not map_mesh.hasRegion3D(region)) { + 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)); + 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)); } } @@ -354,7 +396,7 @@ Field3D FCIMap::integrate(Field3D& f) const { TRACE("FCIMap::integrate"); ASSERT1(f.getDirectionY() == YDirectionType::Standard); - ASSERT1(&map_mesh == f.getMesh()); + ASSERT1(map_mesh == f.getMesh()); // Cell centre values Field3D centre = interp->interpolate(f); @@ -369,7 +411,7 @@ Field3D FCIMap::integrate(Field3D& f) const { #endif BOUT_FOR(i, region_no_boundary) { - const auto inext = i.yp(offset); + const auto inext = i.yp(offset_); const BoutReal f_c = centre[inext]; const auto izm = i.zm(); const int x = i.x(); @@ -378,7 +420,7 @@ Field3D FCIMap::integrate(Field3D& f) const { 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)) { + || (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. @@ -399,10 +441,62 @@ Field3D FCIMap::integrate(Field3D& f) const { return result; } +FCITransform::FCITransform(Mesh& mesh, const Coordinates::FieldMetric& dy, bool zperiodic, + Options* opt) + : ParallelTransform(mesh, opt), R{&mesh}, Z{&mesh} { + + // check the coordinate system used for the grid data source + FCITransform::checkInputGrid(); + + // Real-space coordinates of grid cells + mesh.get(R, "R", 0.0, false); + mesh.get(Z, "Z", 0.0, false); + + auto forward_boundary_xin = + 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 = + 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, 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(static_cast(mesh.ystart) * 2); + for (int offset = 1; offset < mesh.ystart + 1; ++offset) { + field_line_maps.emplace_back(mesh, dy, options, offset, forward_boundary_xin, + forward_boundary_xout, zperiodic); + field_line_maps.emplace_back(mesh, dy, options, -offset, backward_boundary_xin, + backward_boundary_xout, zperiodic); + } + const std::array bndries = {forward_boundary_xin, forward_boundary_xout, + backward_boundary_xin, backward_boundary_xout}; + for (const auto& bndry : bndries) { + for (const auto& bndry2 : bndries) { + if (bndry->dir == bndry2->dir) { + continue; + } + for (auto pnt : *bndry) { + for (auto pnt2 : *bndry2) { + if (pnt.ind() == pnt2.ind()) { + pnt.setValid( + static_cast(std::abs((pnt2.offset() - pnt.offset())) - 2)); + } + } + } + } + } +} + void FCITransform::checkInputGrid() { std::string parallel_transform; if (mesh.isDataSourceGridFile() - && !mesh.get(parallel_transform, "parallel_transform")) { + && (mesh.get(parallel_transform, "parallel_transform") == 0)) { if (parallel_transform != "fci") { throw BoutException( "Incorrect parallel transform type '" + parallel_transform @@ -410,8 +504,8 @@ void FCITransform::checkInputGrid() { "to generate metric components for FCITransform. Should be 'fci'."); } } // else: parallel_transform variable not found in grid input, indicates older input - // file or grid from options so must rely on the user having ensured the type is - // correct + // file or grid from options so must rely on the user having ensured the type is + // correct } void FCITransform::calcParallelSlices(Field3D& f) { @@ -429,8 +523,8 @@ 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)); + f.ynext(map.offset()) = map.interpolate(f); + f.ynext(map.offset()).setRegion(fmt::format("RGN_YPAR_{:+d}", map.offset())); } } @@ -447,7 +541,7 @@ void FCITransform::integrateParallelSlices(Field3D& f) { // Integrate f onto yup and ydown fields for (const auto& map : field_line_maps) { - f.ynext(map.offset) = map.integrate(f); + f.ynext(map.offset()) = map.integrate(f); } } diff --git a/src/mesh/parallel/fci.hxx b/src/mesh/parallel/fci.hxx index 513a1d86c3..71ac35a192 100644 --- a/src/mesh/parallel/fci.hxx +++ b/src/mesh/parallel/fci.hxx @@ -26,6 +26,11 @@ #ifndef BOUT_FCITRANSFORM_H #define BOUT_FCITRANSFORM_H +#include "bout/assert.hxx" +#include "bout/bout_types.hxx" +#include "bout/boutexception.hxx" +#include "bout/coordinates.hxx" +#include "bout/region.hxx" #include #include #include @@ -33,25 +38,26 @@ #include #include +#include #include +class BoundaryRegionPar; +class FieldPerp; +class Field2D; +class Field3D; +class Options; + /// Field line map - contains the coefficients for interpolation class FCIMap { /// Interpolation objects std::unique_ptr interp; // Cell centre std::unique_ptr interp_corner; // Cell corner at (x+1, z+1) -public: - FCIMap() = delete; - FCIMap(Mesh& mesh, const Coordinates::FieldMetric& dy, Options& options, int offset, - const std::shared_ptr& inner_boundary, - const std::shared_ptr& outer_boundary, bool zperiodic); - // The mesh this map was created on - Mesh& map_mesh; + Mesh* map_mesh; /// Direction of map - const int offset; + int offset_; /// region containing all points where the field line has not left the /// domain @@ -59,8 +65,17 @@ public: /// If any of the integration area has left the domain BoutMask corner_boundary_mask; +public: + FCIMap() = delete; + FCIMap(Mesh& mesh, const Coordinates::FieldMetric& dy, Options& options, int offset, + const std::shared_ptr& inner_boundary, + const std::shared_ptr& outer_boundary, bool zperiodic); + + /// Direction of map + int offset() const { return offset_; } + Field3D interpolate(Field3D& f) const { - ASSERT1(&map_mesh == f.getMesh()); + ASSERT1(map_mesh == f.getMesh()); return interp->interpolate(f); } @@ -72,58 +87,7 @@ class FCITransform : public ParallelTransform { public: FCITransform() = delete; FCITransform(Mesh& mesh, const Coordinates::FieldMetric& dy, bool zperiodic = true, - Options* opt = nullptr) - : ParallelTransform(mesh, opt), R{&mesh}, Z{&mesh} { - - // check the coordinate system used for the grid data source - FCITransform::checkInputGrid(); - - // Real-space coordinates of grid cells - mesh.get(R, "R", 0.0, false); - mesh.get(Z, "Z", 0.0, false); - - auto forward_boundary_xin = - 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 = - 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, 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) { - field_line_maps.emplace_back(mesh, dy, options, offset, forward_boundary_xin, - forward_boundary_xout, zperiodic); - field_line_maps.emplace_back(mesh, dy, options, -offset, backward_boundary_xin, - backward_boundary_xout, zperiodic); - } - 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 (auto pnt : *bndry) { - for (auto pnt2 : *bndry2) { -#warning this could likely be done faster - if (pnt.ind() == pnt2.ind()) { - pnt.setValid( - static_cast(std::abs((pnt2.offset() - pnt.offset())) - 2)); - } - } - } - } - } - } + Options* opt = nullptr); void calcParallelSlices(Field3D& f) override; diff --git a/src/solver/impls/arkode/arkode.cxx b/src/solver/impls/arkode/arkode.cxx index 6f20ce11a6..0151f90167 100644 --- a/src/solver/impls/arkode/arkode.cxx +++ b/src/solver/impls/arkode/arkode.cxx @@ -72,6 +72,18 @@ int arkode_pre(BoutReal t, N_Vector yy, N_Vector yp, N_Vector rvec, N_Vector zve int arkode_jac(N_Vector v, N_Vector Jv, BoutReal t, N_Vector y, N_Vector fy, void* user_data, N_Vector tmp); + +#if SUNDIALS_VERSION_LESS_THAN(7, 2, 0) +// Shim for backwards compatibility +int ARKodeGetNumRhsEvals(void* arkode_mem, int partition_index, long int* num_rhs_evals) { + long int temp = 0; + if (partition_index == 0) { + return ARKStepGetNumRhsEvals(arkode_mem, num_rhs_evals, &temp); + } else { + return ARKStepGetNumRhsEvals(arkode_mem, &temp, num_rhs_evals); + } +} +#endif } // namespace // NOLINTEND(readability-identifier-length) @@ -417,8 +429,7 @@ int ArkodeSolver::init() { if (hasPreconditioner()) { output.write("\tUsing user-supplied preconditioner\n"); - if (ARKodeSetPreconditioner(arkode_mem, nullptr, arkode_pre) - != ARKLS_SUCCESS) { + if (ARKodeSetPreconditioner(arkode_mem, nullptr, arkode_pre) != ARKLS_SUCCESS) { throw BoutException("ARKodeSetPreconditioner failed\n"); } } else { @@ -516,12 +527,13 @@ int ArkodeSolver::run() { } // Get additional diagnostics - long int temp_long_int, temp_long_int2; + long int temp_long_int = 0; ARKodeGetNumSteps(arkode_mem, &temp_long_int); nsteps = int(temp_long_int); - ARKStepGetNumRhsEvals(arkode_mem, &temp_long_int, &temp_long_int2); + ARKodeGetNumRhsEvals(arkode_mem, 0, &temp_long_int); nfe_evals = int(temp_long_int); - nfi_evals = int(temp_long_int2); + ARKodeGetNumRhsEvals(arkode_mem, 1, &temp_long_int); + nfi_evals = int(temp_long_int); if (treatment == Treatment::ImEx or treatment == Treatment::Implicit) { ARKodeGetNumNonlinSolvIters(arkode_mem, &temp_long_int); nniters = int(temp_long_int); diff --git a/src/solver/impls/petsc/petsc.cxx b/src/solver/impls/petsc/petsc.cxx index dd63811f0f..ed48d87312 100644 --- a/src/solver/impls/petsc/petsc.cxx +++ b/src/solver/impls/petsc/petsc.cxx @@ -2,9 +2,9 @@ * Interface to PETSc solver * ************************************************************************** - * Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu + * Copyright 2010 - 2025 BOUT++ contributors * - * Contact: Ben Dudson, bd512@york.ac.uk + * Contact: Ben Dudson, dudson2@llnl.gov * * This file is part of BOUT++. * @@ -25,60 +25,253 @@ #include "bout/build_defines.hxx" +#if BOUT_HAS_PETSC + #include "petsc.hxx" -#if BOUT_HAS_PETSC +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef PETSC_UNLIMITED +// Introduced in PETSc 3.22 +#define PETSC_UNLIMITED (-3) +#endif -#include +class ColoringStencil { +private: + bool static isInSquare(int const i, int const j, int const n_square) { + return std::abs(i) <= n_square && std::abs(j) <= n_square; + } + bool static isInCross(int const i, int const j, int const n_cross) { + if (i == 0) { + return std::abs(j) <= n_cross; + } + if (j == 0) { + return std::abs(i) <= n_cross; + } + return false; + } + bool static isInTaxi(int const i, int const j, int const n_taxi) { + return std::abs(i) + std::abs(j) <= n_taxi; + } -#include +public: + auto static getOffsets(int n_square, int n_taxi, int n_cross) { + ASSERT2(n_square >= 0 && n_cross >= 0 && n_taxi >= 0 + && n_square + n_cross + n_taxi > 0); + auto inside = [&](int i, int j) { + return isInSquare(i, j, n_square) || isInTaxi(i, j, n_taxi) + || isInCross(i, j, n_cross); + }; + std::vector> xy_offsets; + auto loop_bound = std::max({n_square, n_taxi, n_cross}); + for (int i = -loop_bound; i <= loop_bound; ++i) { + for (int j = -loop_bound; j <= loop_bound; ++j) { + if (inside(i, j)) { + xy_offsets.emplace_back(i, j); + } + } + } + return xy_offsets; + } +}; -#include // Cell interpolation -#include -#include +namespace { +// PETSc callback function for matrix-free preconditioner +PetscErrorCode snesPCapply(PC pc, Vec x, Vec y) { + // Get the context + void* ctx = nullptr; + PetscCall(PCShellGetContext(pc, &ctx)); + // Run the preconditioner + PetscFunctionReturn(static_cast(ctx)->pre(x, y)); +} + +// PETSc callback function, that evaluates the nonlinear +// function being integrated by TS. +PetscErrorCode solver_rhs(TS UNUSED(ts), BoutReal t, Vec globalin, Vec globalout, + void* f_data) { + PetscFunctionBegin; + auto* s = static_cast(f_data); + s->rhs(t, globalin, globalout, false); + PetscFunctionReturn(0); +} + +// Form function for use with SUNDIALS. +// This is needed because SNESTSFormFunction is not available +// PETSc error: No method snesfunction for TS of type sundials +PetscErrorCode solver_form_function(void* UNUSED(dummy), Vec U, Vec F, void* f_data) { + PetscFunctionBegin; + auto* s = static_cast(f_data); + s->formFunction(U, F); + PetscFunctionReturn(0); +} +} // namespace + +// Compute IJacobian = dF/dU + a dF/dUdot +// This is a dummy matrix that saves the shift. +// The shift is later used in the matrix-free preconditioner +PetscErrorCode solver_ijacobian(TS, BoutReal, Vec, Vec, PetscReal shift, Mat J, Mat Jpre, + void* ctx) { + auto* solver = static_cast(ctx); + solver->shift = shift; + + PetscCall(MatAssemblyBegin(Jpre, MAT_FINAL_ASSEMBLY)); + PetscCall(MatAssemblyEnd(Jpre, MAT_FINAL_ASSEMBLY)); + if (J != Jpre) { + PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); + PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); + } + + PetscFunctionReturn(0); +} + +PetscErrorCode solver_ijacobian_color(TS ts, PetscReal t, Vec U, Vec Udot, + PetscReal shift, Mat J, Mat B, void* ctx) { + auto* solver = static_cast(ctx); + solver->shift = shift; + + return TSComputeIJacobianDefaultColor(ts, t, U, Udot, shift, J, B, nullptr); +} + +// This function is called by the TS object every internal timestep +// It is responsible for triggering interpolation and output at +// the output time interval. +PetscErrorCode PetscMonitor(TS ts, PetscInt UNUSED(step), PetscReal t, Vec X, void* ctx) { + PetscFunctionBegin; + + auto* s = static_cast(ctx); + if (t < s->next_output) { + // Not reached output time yet => return + PetscFunctionReturn(0); + } -extern PetscErrorCode solver_f(TS ts, BoutReal t, Vec globalin, Vec globalout, - void* f_data); + PetscReal tfinal; + static int i = 0; -#if PETSC_VERSION_GE(3, 5, 0) -extern PetscErrorCode solver_rhsjacobian(TS ts, BoutReal t, Vec globalin, Mat J, Mat Jpre, - void* f_data); -extern PetscErrorCode solver_ijacobianfd(TS, PetscReal, Vec, Vec, PetscReal, Mat, Mat, - void*); +#if PETSC_VERSION_GE(3, 8, 0) + PetscCall(TSGetMaxTime(ts, &tfinal)); #else -extern PetscErrorCode solver_rhsjacobian(TS ts, BoutReal t, Vec globalin, Mat* J, - Mat* Jpre, MatStructure* str, void* f_data); -extern PetscErrorCode solver_ijacobianfd(TS, PetscReal, Vec, Vec, PetscReal, Mat*, Mat*, - MatStructure*, void*); + PetscCall(TSGetDuration(ts, nullptr, &tfinal)); #endif -extern PetscErrorCode solver_if(TS, BoutReal, Vec, Vec, Vec, void*); + // Duplicate the solution vector X into a work vector + Vec interpolatedX; + PetscCall(VecDuplicate(X, &interpolatedX)); + + // The internal timestepper may have stepped over multiple output times + while (s->next_output <= t && s->next_output <= tfinal) { + BoutReal output_time = t; + if (s->interpolate) { + int ierr = TSInterpolate(ts, s->next_output, interpolatedX); + if (ierr != PETSC_SUCCESS) { + throw BoutException("This PETSc TS does not support interpolation. Use a " + "different method or set solver:interpolate=false"); + } + output_time = s->next_output; + } -/// KSP preconditioner PCShell routines for physics preconditioners -extern PetscErrorCode PhysicsPCApply(PC, Vec x, Vec y); -extern PetscErrorCode PhysicsJacobianApply(Mat J, Vec x, Vec y); -extern PetscErrorCode PhysicsSNESApply(SNES, Vec); + // Place the interpolated values into the global variables + const PetscScalar* x; + PetscCall(VecGetArrayRead(interpolatedX, &x)); + s->load_vars(const_cast(x)); + PetscCall(VecRestoreArrayRead(interpolatedX, &x)); + + if (s->call_monitors(output_time, i++, s->getNumberOutputSteps()) != 0) { + PetscFunctionReturn(1); + } + + s->next_output = output_time + s->getOutputTimestep(); + } + + // Done with vector, so destroy it + PetscCall(VecDestroy(&interpolatedX)); + + PetscFunctionReturn(0); +} PetscSolver::PetscSolver(Options* opts) - : Solver(opts), + : Solver(opts), interpolate((*options)["interpolate"] + .doc("Interpolate to regular output times?") + .withDefault(true)), diagnose( (*options)["diagnose"].doc("Enable some diagnostic output").withDefault(false)), - adaptive( - (*options)["adaptive"].doc("Use adaptive timestepping").withDefault(false)), - use_precon((*options)["use_precon"] - .doc("Use user-supplied preconditioning function") - .withDefault(false)), - use_jacobian((*options)["use_jacobian"] - .doc("Use user-supplied Jacobian function") - .withDefault(false)), - abstol((*options)["atol"].doc("Absolute tolerance").withDefault(1.0e-12)), - reltol((*options)["rtol"].doc("Relative tolerance").withDefault(1.0e-5)), - adams_moulton((*options)["adams_moulton"] - .doc("Use Adams-Moulton implicit multistep method instead of BDF " - "(requires PETSc to have been built with SUNDIALS)") - .withDefault(false)), + user_precon((*options)["user_precon"] + .doc("Use user-supplied preconditioning function?") + .withDefault(false)), + atol((*options)["atol"].doc("Absolute tolerance").withDefault(1.0e-12)), + rtol((*options)["rtol"].doc("Relative tolerance").withDefault(1.0e-5)), + stol((*options)["stol"] + .doc("Convergence tolerance in terms of the norm of the change in " + "the solution between steps") + .withDefault(1e-8)), + maxnl((*options)["max_nonlinear_iterations"] + .doc("Maximum number of nonlinear iterations per SNES solve") + .withDefault(50)), + maxf((*options)["maxf"] + .doc("Maximum number of function evaluations per SNES solve") + .withDefault(10000)), + maxl((*options)["maxl"].doc("Maximum number of linear iterations").withDefault(20)), + ts_type((*options)["ts_type"].doc("PETSc time integrator type").withDefault("bdf")), + adapt_type((*options)["adapt_type"] + .doc("PETSc TSAdaptType timestep adaptation method") + .withDefault("basic")), + snes_type((*options)["snes_type"] + .doc("PETSc nonlinear solver method to use") + .withDefault("newtonls")), + ksp_type((*options)["ksp_type"] + .doc("Linear solver type. By default let PETSc decide (gmres)") + .withDefault("default")), + pc_type( + (*options)["pc_type"] + .doc("Preconditioner type. By default lets PETSc decide (ilu or bjacobi)") + .withDefault("default")), + pc_hypre_type((*options)["pc_hypre_type"] + .doc("hypre preconditioner type: euclid, pilut, parasails, " + "boomeramg, ams, ads") + .withDefault("pilut")), + line_search_type((*options)["line_search_type"] + .doc("Line search type: basic, bt, l2, cp, nleqerr") + .withDefault("default")), + matrix_free((*options)["matrix_free"] + .doc("Use matrix free Jacobian?") + .withDefault(false)), + matrix_free_operator((*options)["matrix_free_operator"] + .doc("Use matrix free Jacobian-vector operator?") + .withDefault(false)), + lag_jacobian((*options)["lag_jacobian"] + .doc("Re-use the Jacobian this number of SNES iterations") + .withDefault(50)), + use_coloring((*options)["use_coloring"] + .doc("Use matrix coloring to calculate Jacobian?") + .withDefault(true)), + kspsetinitialguessnonzero((*options)["kspsetinitialguessnonzero"] + .doc("Set the initial guess to be non-zero") + .withDefault(false)), start_timestep((*options)["start_timestep"] .doc("Initial internal timestep (defaults to output timestep)") .withDefault(getOutputTimestep())), @@ -87,9 +280,9 @@ PetscSolver::PetscSolver(Options* opts) PetscSolver::~PetscSolver() { VecDestroy(&u); - MatDestroy(&J); + MatDestroy(&Jfd); MatDestroy(&Jmf); - MatFDColoringDestroy(&matfdcoloring); + MatFDColoringDestroy(&fdcoloring); TSDestroy(&ts); } @@ -98,133 +291,72 @@ PetscSolver::~PetscSolver() { **************************************************************************/ int PetscSolver::init() { - PetscErrorCode ierr; - int neq; - MPI_Comm comm = PETSC_COMM_WORLD; - PetscMPIInt rank; TRACE("Initialising PETSc-dev solver"); - PetscFunctionBegin; - PetscLogEventRegister("PetscSolver::init", PETSC_VIEWER_CLASSID, &init_event); - PetscLogEventRegister("loop_vars", PETSC_VIEWER_CLASSID, &loop_event); - PetscLogEventRegister("solver_f", PETSC_VIEWER_CLASSID, &solver_event); - Solver::init(); - ierr = PetscLogEventBegin(init_event, 0, 0, 0, 0); - CHKERRQ(ierr); - output.write("Initialising PETSc-dev solver\n"); - ierr = bout::globals::mpi->MPI_Comm_rank(comm, &rank); - CHKERRQ(ierr); - - PetscInt local_N = getLocalN(); // Number of evolving variables on this processor - - /********** Get total problem size **********/ - if (bout::globals::mpi->MPI_Allreduce(&local_N, &neq, 1, MPI_INT, MPI_SUM, - BoutComm::get())) { - output_error.write("\tERROR: MPI_Allreduce failed!\n"); - ierr = PetscLogEventEnd(init_event, 0, 0, 0, 0); - CHKERRQ(ierr); - PetscFunctionReturn(1); + int nlocal = getLocalN(); // Number of evolving variables on this processor + + // Get total problem size + int neq; + if (bout::globals::mpi->MPI_Allreduce(&nlocal, &neq, 1, MPI_INT, MPI_SUM, + BoutComm::get()) + != 0) { + throw BoutException("MPI_Allreduce failed!"); } - ierr = VecCreate(BoutComm::get(), &u); - CHKERRQ(ierr); - ierr = VecSetSizes(u, local_N, PETSC_DECIDE); - CHKERRQ(ierr); - ierr = VecSetFromOptions(u); - CHKERRQ(ierr); + output_info.write("\t3d fields = {:d}, 2d fields = {:d} neq={:d}, local_N={:d}\n", + n3Dvars(), n2Dvars(), neq, nlocal); - ////////// SAVE INITIAL STATE TO PETSc VECTOR /////////// - // Set pointer to data array in vector u. - BoutReal* udata; + // Create a vector to contain the state + PetscCall(VecCreate(BoutComm::get(), &u)); + PetscCall(VecSetSizes(u, nlocal, PETSC_DECIDE)); + PetscCall(VecSetFromOptions(u)); - ierr = VecGetArray(u, &udata); - CHKERRQ(ierr); + // Save initial state to PETSc Vec + BoutReal* udata; // Pointer to data array in vector u. + PetscCall(VecGetArray(u, &udata)); save_vars(udata); - ierr = VecRestoreArray(u, &udata); - CHKERRQ(ierr); - - PetscReal norm; - ierr = VecNorm(u, NORM_1, &norm); - CHKERRQ(ierr); - output_info << "initial |u| = " << norm << "\n"; - - PetscBool J_load; - char load_file[PETSC_MAX_PATH_LEN]; /* jacobian input file name */ - PetscBool J_write = PETSC_FALSE, J_slowfd = PETSC_FALSE; + PetscCall(VecRestoreArray(u, &udata)); // Create timestepper - ierr = TSCreate(BoutComm::get(), &ts); - CHKERRQ(ierr); - ierr = TSSetProblemType(ts, TS_NONLINEAR); - CHKERRQ(ierr); -#if PETSC_HAS_SUNDIALS - ierr = TSSetType(ts, TSSUNDIALS); - CHKERRQ(ierr); -#else - ierr = TSSetType(ts, TSRK); - CHKERRQ(ierr); -#endif - ierr = TSSetApplicationContext(ts, this); - CHKERRQ(ierr); + PetscCall(TSCreate(BoutComm::get(), &ts)); + PetscCall(TSSetProblemType(ts, TS_NONLINEAR)); + PetscCall(TSSetType(ts, ts_type.c_str())); + PetscCall(TSSetApplicationContext(ts, this)); // Set user provided RHSFunction // Need to duplicate the solution vector for the residual Vec rhs_vec; - ierr = VecDuplicate(u, &rhs_vec); - CHKERRQ(ierr); - ierr = TSSetRHSFunction(ts, rhs_vec, solver_f, this); - CHKERRQ(ierr); - ierr = VecDestroy(&rhs_vec); - CHKERRQ(ierr); + PetscCall(VecDuplicate(u, &rhs_vec)); + PetscCall(TSSetRHSFunction(ts, rhs_vec, solver_rhs, this)); // Set up adaptive time-stepping TSAdapt adapt; - ierr = TSGetAdapt(ts, &adapt); - CHKERRQ(ierr); - if (adaptive) { - ierr = TSAdaptSetType(adapt, TSADAPTBASIC); - CHKERRQ(ierr); - } else { - ierr = TSAdaptSetType(adapt, TSADAPTNONE); - CHKERRQ(ierr); - } + PetscCall(TSGetAdapt(ts, &adapt)); + PetscCall(TSAdaptSetType(adapt, adapt_type.c_str())); // Set default absolute/relative tolerances - ierr = TSSetTolerances(ts, abstol, nullptr, reltol, nullptr); - CHKERRQ(ierr); - -#if PETSC_VERSION_LT(3, 5, 0) - ierr = TSRKSetTolerance(ts, reltol); - CHKERRQ(ierr); + // Note: Vector atol and rtol not given + PetscCall(TSSetTolerances(ts, atol, nullptr, rtol, nullptr)); + if (ts_type == TSSUNDIALS) { +#if PETSC_HAVE_SUNDIALS2 + // The PETSc interface to SUNDIALS' CVODE + TSSundialsSetType(ts, SUNDIALS_BDF); + TSSundialsSetTolerance(ts, atol, rtol); +#else + throw BoutException("PETSc was not built with SUNDIALS. Reconfigure and build PETSc " + "with --download-sundials"); #endif - -#if PETSC_HAS_SUNDIALS - // Set Sundials tolerances - ierr = TSSundialsSetTolerance(ts, abstol, reltol); - CHKERRQ(ierr); - - // Select Sundials Adams-Moulton or BDF method - if (adams_moulton) { - output.write("\tUsing Adams-Moulton implicit multistep method\n"); - ierr = TSSundialsSetType(ts, SUNDIALS_ADAMS); - CHKERRQ(ierr); - } else { - output.write("\tUsing BDF method\n"); - ierr = TSSundialsSetType(ts, SUNDIALS_BDF); - CHKERRQ(ierr); } -#endif - // Initial time and timestep - ierr = TSSetTime(ts, simtime); - CHKERRQ(ierr); - ierr = TSSetTimeStep(ts, start_timestep); - CHKERRQ(ierr); + // Initial time of the simulation state + PetscCall(TSSetTime(ts, simtime)); next_output = simtime; + PetscCall(TSSetTimeStep(ts, start_timestep)); + // Total number of steps PetscInt total_steps = mxstep * getNumberOutputSteps(); // Final output time @@ -233,389 +365,549 @@ int PetscSolver::init() { simtime); #if PETSC_VERSION_GE(3, 8, 0) - ierr = TSSetMaxSteps(ts, total_steps); - CHKERRQ(ierr); - ierr = TSSetMaxTime(ts, tfinal); - CHKERRQ(ierr); + PetscCall(TSSetMaxSteps(ts, total_steps)); + PetscCall(TSSetMaxTime(ts, tfinal)); #else - ierr = TSSetDuration(ts, total_steps, tfinal); - CHKERRQ(ierr); + PetscCall(TSSetDuration(ts, total_steps, tfinal)); #endif - // Set the current solution - ierr = TSSetSolution(ts, u); - CHKERRQ(ierr); - - // Create RHSJacobian J - SNES snes, psnes; - KSP ksp, nksp; - PC pc, npc; - PCType pctype; - TSType tstype; - PetscBool pcnone = PETSC_TRUE; - - ierr = TSGetSNES(ts, &snes); - CHKERRQ(ierr); - ierr = TSSetExactFinalTime(ts, TS_EXACTFINALTIME_INTERPOLATE); - CHKERRQ(ierr); - -#if PETSC_VERSION_GE(3, 7, 0) - ierr = PetscOptionsGetBool(nullptr, nullptr, "-interpolate", &interpolate, nullptr); - CHKERRQ(ierr); -#else - ierr = PetscOptionsGetBool(nullptr, "-interpolate", &interpolate, nullptr); - CHKERRQ(ierr); -#endif + // Allow TS to recover from SNES failures + PetscCall(TSSetMaxSNESFailures(ts, PETSC_UNLIMITED)); - // Check for -output_name to see if user specified a "performance" - // run, if they didn't then use the standard monitor function. TODO: - // use PetscFList -#if PETSC_VERSION_GE(3, 7, 0) - ierr = PetscOptionsGetString(nullptr, nullptr, "-output_name", this->output_name, - sizeof this->output_name, &output_flag); - CHKERRQ(ierr); -#else - ierr = PetscOptionsGetString(nullptr, "-output_name", this->output_name, - sizeof this->output_name, &output_flag); - CHKERRQ(ierr); -#endif + // Recover from step rejections + PetscCall(TSSetMaxStepRejections(ts, PETSC_UNLIMITED)); - // If the output_name is not specified then use the standard monitor function - if (output_flag != 0U) { - ierr = SNESMonitorSet(snes, PetscSNESMonitor, this, nullptr); - CHKERRQ(ierr); - } else { - ierr = TSMonitorSet(ts, PetscMonitor, this, nullptr); - CHKERRQ(ierr); - } - - ierr = SNESSetTolerances(snes, abstol, reltol, PETSC_DEFAULT, PETSC_DEFAULT, - PETSC_DEFAULT); - CHKERRQ(ierr); - - // Matrix free Jacobian - - if (use_jacobian and hasJacobian()) { - // Use a user-supplied Jacobian function - ierr = MatCreateShell(comm, local_N, local_N, neq, neq, this, &Jmf); - CHKERRQ(ierr); - ierr = MatShellSetOperation(Jmf, MATOP_MULT, - reinterpret_cast(PhysicsJacobianApply)); - CHKERRQ(ierr); - ierr = TSSetIJacobian(ts, Jmf, Jmf, solver_ijacobian, this); - CHKERRQ(ierr); + // Set the current solution + PetscCall(TSSetSolution(ts, u)); + // Allow TS to step over the final time + // Note: This does not affect intermediate outputs, that + // are always interpolated (in PetscMonitor) + if (interpolate) { + PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_INTERPOLATE)); } else { - // Use finite difference approximation - ierr = MatCreateSNESMF(snes, &Jmf); - CHKERRQ(ierr); - ierr = SNESSetJacobian(snes, Jmf, Jmf, MatMFFDComputeJacobian, this); - CHKERRQ(ierr); + PetscCall(TSSetExactFinalTime(ts, TS_EXACTFINALTIME_MATCHSTEP)); } + PetscCall(TSMonitorSet(ts, PetscMonitor, this, nullptr)); - ierr = SNESGetKSP(snes, &ksp); - CHKERRQ(ierr); + if (ts_type != TSSUNDIALS) { + // Get and configure the SNES nonlinear solver + // Note: SUNDIALS does not use PETSc SNES or KSP + // https://petsc.org/release/manual/ts/#using-sundials-from-petsc - ierr = KSPSetTolerances(ksp, reltol, abstol, PETSC_DEFAULT, PETSC_DEFAULT); - CHKERRQ(ierr); + PetscCall(TSGetSNES(ts, &snes)); + PetscCall(SNESSetType(snes, snes_type.c_str())); - ierr = KSPGetPC(ksp, &pc); - CHKERRQ(ierr); + // Line search + if (line_search_type != "default") { + SNESLineSearch linesearch; + SNESGetLineSearch(snes, &linesearch); + SNESLineSearchSetType(linesearch, line_search_type.c_str()); + } - if (use_precon and hasPreconditioner()) { + // Set tolerances + // Note: TS should set SNES convergence tolerances + SNESSetTolerances(snes, + PETSC_DETERMINE, // atol + PETSC_DETERMINE, // rtol + PETSC_DETERMINE, // stol + maxnl, maxf); -#if PETSC_VERSION_GE(3, 5, 0) - ierr = SNESGetNPC(snes, &psnes); - CHKERRQ(ierr); -#else - ierr = SNESGetPC(snes, &psnes); - CHKERRQ(ierr); + // Force SNES to take at least one nonlinear iteration. + // This may prevent the solver from getting stuck in false steady state conditions +#if PETSC_VERSION_GE(3, 8, 0) + SNESSetForceIteration(snes, PETSC_TRUE); #endif - ierr = SNESGetKSP(psnes, &nksp); - CHKERRQ(ierr); - ierr = KSPGetPC(nksp, &npc); - CHKERRQ(ierr); - ierr = SNESSetType(psnes, SNESSHELL); - CHKERRQ(ierr); - ierr = SNESShellSetSolve(psnes, PhysicsSNESApply); - CHKERRQ(ierr); - - // Use a user-supplied preconditioner - // Tell PETSc we're using a "shell" preconditioner - ierr = PCSetType(pc, PCSHELL); - CHKERRQ(ierr); + // Re-use Jacobian + // Note: If the 'Amat' Jacobian is matrix free, SNESComputeJacobian + // always updates its reference 'u' vector every nonlinear iteration + SNESSetLagJacobian(snes, lag_jacobian); + SNESSetLagJacobianPersists(snes, PETSC_TRUE); - // Set routine for applying preconditioner - ierr = PCShellSetApply(pc, PhysicsPCApply); - CHKERRQ(ierr); + SNESSetLagPreconditionerPersists(snes, PETSC_TRUE); + SNESSetLagPreconditioner(snes, 1); // Rebuild when Jacobian is rebuilt - // Set context to this solver object - ierr = PCShellSetContext(pc, this); - CHKERRQ(ierr); + // Get and configure the KSP linear solver + SNESGetKSP(snes, &ksp); - // Set name of preconditioner - ierr = PCShellSetName(pc, "PhysicsPreconditioner"); - CHKERRQ(ierr); - - // Need a callback for IJacobian to get shift 'alpha' - ierr = TSSetIJacobian(ts, Jmf, Jmf, solver_ijacobian, this); - CHKERRQ(ierr); + if (ksp_type != "default") { + KSPSetType(ksp, ksp_type.c_str()); + } - // Use right preconditioner - ierr = KSPSetPCSide(ksp, PC_RIGHT); - CHKERRQ(ierr); + if (kspsetinitialguessnonzero) { + // Set the initial guess to be non-zero + KSPSetInitialGuessNonzero(ksp, PETSC_TRUE); + } - } else { - // Default to no preconditioner - ierr = PCSetType(pc, PCNONE); - CHKERRQ(ierr); - } - ierr = TSSetFromOptions(ts); - CHKERRQ(ierr); // enable PETSc runtime options - - ierr = PCGetType(pc, &pctype); - CHKERRQ(ierr); - ierr = TSGetType(ts, &tstype); - CHKERRQ(ierr); - output.write("\tTS type {:s}, PC type {:s}\n", tstype, pctype); - - ierr = PetscObjectTypeCompare(reinterpret_cast(pc), PCNONE, &pcnone); - CHKERRQ(ierr); - if (pcnone) { - ierr = PetscLogEventEnd(init_event, 0, 0, 0, 0); - CHKERRQ(ierr); - PetscFunctionReturn(0); - } - ierr = PetscObjectTypeCompare(reinterpret_cast(pc), PCSHELL, &pcnone); - CHKERRQ(ierr); - if (pcnone) { - ierr = PetscLogEventEnd(init_event, 0, 0, 0, 0); - CHKERRQ(ierr); - PetscFunctionReturn(0); + KSPSetTolerances(ksp, + PETSC_DEFAULT, // rtol + PETSC_DEFAULT, // abstol + PETSC_DEFAULT, // dtol (divergence tolerance) + maxl); // Maximum number of iterations + + // Set up the Jacobian + // Note: We can have both matrix-free Jacobian-vector operator (Jmf) + // and a finite-difference Jacobian matrix (Jfd) + if (matrix_free or matrix_free_operator) { + /* + PETSc SNES matrix free Jacobian, using a different + operator for differencing. + + See PETSc examples + http://www.mcs.anl.gov/petsc/petsc-current/src/snes/examples/tests/ex7.c.html + and this thread: + http://lists.mcs.anl.gov/pipermail/petsc-users/2014-January/020075.html + + */ + MatCreateSNESMF(snes, &Jmf); + + // Set a function to be called for differencing + // This can be a linearised form of the SNES function + // Note: Unsure if setting this will interfere with TS object + // because the SNES Jacobian depends on the timestep + //MatMFFDSetFunction(Jmf, solver_rhs_differencing, this); + } } - // Create Jacobian matrix to be used by preconditioner - output_info << " Get Jacobian matrix at simtime " << simtime << "\n"; -#if PETSC_VERSION_GE(3, 7, 0) - ierr = PetscOptionsGetString(nullptr, nullptr, "-J_load", load_file, - PETSC_MAX_PATH_LEN - 1, &J_load); - CHKERRQ(ierr); -#else - ierr = PetscOptionsGetString(nullptr, "-J_load", load_file, PETSC_MAX_PATH_LEN - 1, - &J_load); - CHKERRQ(ierr); -#endif - if (J_load) { - PetscViewer fd; - output_info << " Load Jmat ...local_N " << local_N << " neq " << neq << "\n"; - ierr = PetscViewerBinaryOpen(comm, load_file, FILE_MODE_READ, &fd); - CHKERRQ(ierr); - ierr = MatCreate(PETSC_COMM_WORLD, &J); - CHKERRQ(ierr); - //ierr = MatSetType(J, MATBAIJ);CHKERRQ(ierr); - ierr = MatSetSizes(J, local_N, local_N, PETSC_DECIDE, PETSC_DECIDE); - CHKERRQ(ierr); - ierr = MatSetFromOptions(J); - CHKERRQ(ierr); - ierr = MatLoad(J, fd); - CHKERRQ(ierr); - ierr = PetscViewerDestroy(&fd); - CHKERRQ(ierr); - } else { // create Jacobian matrix - - /* number of degrees (variables) at each grid point */ - PetscInt dof = n3Dvars(); - - // Maximum allowable size of stencil in x is the number of guard cells - PetscInt stencil_width_estimate = options->operator[]("stencil_width_estimate") - .withDefault(bout::globals::mesh->xstart); - // This is the stencil in each direction (*2) along each dimension - // (*3), plus the point itself. Not sure if this is correct - // though, on several levels: - // 1. Ignores corner points used in e.g. brackets - // 2. Could have different stencil widths in each dimension - // 3. FFTs couple every single point together - PetscInt cols = stencil_width_estimate * 2 * 3 + 1; - PetscInt prealloc; // = cols*dof; - - ierr = MatCreate(comm, &J); - CHKERRQ(ierr); - ierr = MatSetType(J, MATBAIJ); - CHKERRQ(ierr); - ierr = MatSetSizes(J, local_N, local_N, neq, neq); - CHKERRQ(ierr); - ierr = MatSetFromOptions(J); - CHKERRQ(ierr); - - // Get nonzero pattern of J - color_none !!! - prealloc = cols * dof * dof; - ierr = MatSeqAIJSetPreallocation(J, prealloc, nullptr); - CHKERRQ(ierr); - ierr = MatMPIAIJSetPreallocation(J, prealloc, nullptr, prealloc, nullptr); - CHKERRQ(ierr); - - // why nonzeros=295900, allocated nonzeros=2816000/12800000 (*dof*dof), number of mallocs used during MatSetValues calls =256? - prealloc = cols; - ierr = MatSeqBAIJSetPreallocation(J, dof, prealloc, nullptr); - CHKERRQ(ierr); - ierr = MatMPIBAIJSetPreallocation(J, dof, prealloc, nullptr, prealloc, nullptr); - CHKERRQ(ierr); -#if PETSC_VERSION_GE(3, 7, 0) - ierr = PetscOptionsHasName(nullptr, nullptr, "-J_slowfd", &J_slowfd); - CHKERRQ(ierr); -#else - ierr = PetscOptionsHasName(nullptr, "-J_slowfd", &J_slowfd); - CHKERRQ(ierr); -#endif - if (J_slowfd != 0U) { // create Jacobian matrix by slow fd - ierr = SNESSetJacobian(snes, J, J, SNESComputeJacobianDefault, nullptr); - CHKERRQ(ierr); - output_info << "SNESComputeJacobian J by slow fd...\n"; - -#if PETSC_VERSION_GE(3, 5, 0) - ierr = TSComputeRHSJacobian(ts, simtime, u, J, J); - CHKERRQ(ierr); -#else - MatStructure flg; - ierr = TSComputeRHSJacobian(ts, simtime, u, &J, &J, &flg); - CHKERRQ(ierr); + // Configure preconditioner + PC pc; + if (ts_type == TSSUNDIALS) { +#if PETSC_HAVE_SUNDIALS2 + TSSundialsGetPC(ts, &pc); #endif - output_info << "compute J by slow fd is done.\n"; - } else { // get sparse pattern of the Jacobian - throw BoutException("Sorry, unimplemented way of setting PETSc preconditioner. " - "Either set a preconditioner function with 'setPrecon' " - "in your code, or load a matrix with '-Jload' on the " - "command line, or calculate with finite differences " - "with '-J_slowfd' (on command line)"); - } + } else { + // Get PC context from KSP + KSPGetPC(ksp, &pc); } + if (matrix_free) { + // Matrix-free preconditioner - // Create coloring context of J to be used during time stepping + if (user_precon) { + output_info.write("\tUsing user-supplied preconditioner\n"); + if (!hasPreconditioner()) { + throw BoutException("Model does not define a preconditioner"); + } + // Set a Shell (matrix-free) preconditioner type + PCSetType(pc, PCSHELL); - output_info << " Create coloring ...\n"; + // Specify the preconditioner function + PCShellSetApply(pc, snesPCapply); - ISColoring iscoloring; -#if PETSC_VERSION_GE(3, 5, 0) - MatColoring coloring; - MatColoringCreate(Jmf, &coloring); - MatColoringSetType(coloring, MATCOLORINGSL); - MatColoringSetFromOptions(coloring); - // Calculate index sets - MatColoringApply(coloring, &iscoloring); - MatColoringDestroy(&coloring); -#else - ierr = MatGetColoring(J, MATCOLORINGSL, &iscoloring); - CHKERRQ(ierr); -#endif - ierr = MatFDColoringCreate(J, iscoloring, &matfdcoloring); - CHKERRQ(ierr); - - ierr = MatFDColoringSetFromOptions(matfdcoloring); - CHKERRQ(ierr); - ierr = ISColoringDestroy(&iscoloring); - CHKERRQ(ierr); - throw BoutException("Coloring is not working"); - ierr = SNESSetJacobian(snes, J, J, SNESComputeJacobianDefaultColor, matfdcoloring); - CHKERRQ(ierr); - - // Write J in binary for study - see ~petsc/src/mat/examples/tests/ex124.c -#if PETSC_VERSION_GE(3, 7, 0) - ierr = PetscOptionsHasName(nullptr, nullptr, "-J_write", &J_write); - CHKERRQ(ierr); -#else - ierr = PetscOptionsHasName(nullptr, "-J_write", &J_write); - CHKERRQ(ierr); -#endif - if (J_write != 0U) { - PetscViewer viewer = nullptr; - output_info.write("\n[{:d}] Test TSComputeRHSJacobian() ...\n", rank); -#if PETSC_VERSION_GE(3, 5, 0) - ierr = TSComputeRHSJacobian(ts, simtime, u, J, J); - CHKERRQ(ierr); + // Context used to supply object pointer + PCShellSetContext(pc, this); + + // Set name of preconditioner + PetscCall(PCShellSetName(pc, "PhysicsPreconditioner")); + } else { + // Can't use preconditioner because no Jacobian matrix available + PCSetType(pc, PCNONE); + } + + // Callback to get the shift parameter + // Use matrix free for both operator and preconditioner + TSSetIJacobian(ts, Jmf, Jmf, solver_ijacobian, this); + + } else { + // Set PC type from input + if (pc_type != "default") { + PCSetType(pc, pc_type.c_str()); + + if (pc_type == "hypre") { +#if PETSC_HAVE_HYPRE + // Set the type of hypre preconditioner + PCHYPRESetType(pc, pc_hypre_type.c_str()); #else - MatStructure J_structure; - ierr = TSComputeRHSJacobian(ts, simtime, u, &J, &J, &J_structure); - CHKERRQ(ierr); + throw BoutException("PETSc was not configured with Hypre."); #endif + } + } - output.write("[{:d}] TSComputeRHSJacobian is done\n", rank); + // Calculate a Jacobian matrix using finite differences. The finite + // difference Jacobian (Jfd) may be used for both operator and + // preconditioner or, if matrix_free_operator, in only the + // preconditioner. + + if (use_coloring) { + // Use matrix coloring. This greatly reduces the number of + // times the rhs() function needs to be evaluated when + // calculating the Jacobian, by identifying which quantities may + // be simultaneously perturbed. + + // Use global mesh for now + Mesh* mesh = bout::globals::mesh; + + ////////////////////////////////////////////////// + // Get the local indices by starting at 0 + Field3D index = globalIndex(0); + + ////////////////////////////////////////////////// + // Pre-allocate PETSc storage + + output_progress.write("Setting Jacobian matrix sizes\n"); + + const int n2d = f2d.size(); + const int n3d = f3d.size(); + + // Set size of Matrix on each processor to nlocal x nlocal + MatCreate(BoutComm::get(), &Jfd); + MatSetOption(Jfd, MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE); + MatSetSizes(Jfd, nlocal, nlocal, PETSC_DETERMINE, PETSC_DETERMINE); + MatSetFromOptions(Jfd); + // Determine which row/columns of the matrix are locally owned + int Istart, Iend; + MatGetOwnershipRange(Jfd, &Istart, &Iend); + // Convert local into global indices + // Note: Not in the boundary cells, to keep -1 values + for (const auto& i : mesh->getRegion3D("RGN_NOBNDRY")) { + index[i] += Istart; + } + // Now communicate to fill guard cells + mesh->communicate(index); + + // Non-zero elements on this processor + std::vector d_nnz; + std::vector o_nnz; + auto n_square = (*options)["stencil:square"] + .doc("Extent of stencil (square)") + .withDefault(0); + auto n_taxi = (*options)["stencil:taxi"] + .doc("Extent of stencil (taxi-cab norm)") + .withDefault(0); + auto n_cross = (*options)["stencil:cross"] + .doc("Extent of stencil (cross)") + .withDefault(0); + // Set n_taxi 2 if nothing else is set + // Probably a better way to do this + if (n_square == 0 && n_taxi == 0 && n_cross == 0) { + output_info.write("Setting solver:stencil:taxi = 2\n"); + n_taxi = 2; + } + + auto const xy_offsets = ColoringStencil::getOffsets(n_square, n_taxi, n_cross); + { + // This is ugly but can't think of a better and robust way to + // count the non-zeros for some arbitrary stencil + // effectively the same loop as the one that sets the non-zeros below + std::vector> d_nnz_map2d(nlocal); + std::vector> o_nnz_map2d(nlocal); + std::vector> d_nnz_map3d(nlocal); + std::vector> o_nnz_map3d(nlocal); + // Loop over every element in 2D to count the *unique* non-zeros + for (int x = mesh->xstart; x <= mesh->xend; x++) { + for (int y = mesh->ystart; y <= mesh->yend; y++) { + + const int ind0 = ROUND(index(x, y, 0)) - Istart; + + // 2D fields + for (int i = 0; i < n2d; i++) { + const PetscInt row = ind0 + i; + // Loop through each point in the stencil + for (const auto& [x_off, y_off] : xy_offsets) { + const int xi = x + x_off; + const int yi = y + y_off; + if ((xi < 0) || (yi < 0) || (xi >= mesh->LocalNx) + || (yi >= mesh->LocalNy)) { + continue; + } + + const int ind2 = ROUND(index(xi, yi, 0)); + if (ind2 < 0) { + continue; // A boundary point + } + + // Depends on all variables on this cell + for (int j = 0; j < n2d; j++) { + const PetscInt col = ind2 + j; + if (col >= Istart && col < Iend) { + d_nnz_map2d[row].insert(col); + } else { + o_nnz_map2d[row].insert(col); + } + } + } + } + // 3D fields + for (int z = 0; z < mesh->LocalNz; z++) { + const int ind = ROUND(index(x, y, z)) - Istart; + + for (int i = 0; i < n3d; i++) { + PetscInt row = ind + i; + if (z == 0) { + row += n2d; + } + + // Depends on 2D fields + for (int j = 0; j < n2d; j++) { + const PetscInt col = ind0 + j; + if (col >= Istart && col < Iend) { + d_nnz_map2d[row].insert(col); + } else { + o_nnz_map2d[row].insert(col); + } + } + + // Star pattern + for (const auto& [x_off, y_off] : xy_offsets) { + const int xi = x + x_off; + const int yi = y + y_off; + + if ((xi < 0) || (yi < 0) || (xi >= mesh->LocalNx) + || (yi >= mesh->LocalNy)) { + continue; + } + + int ind2 = ROUND(index(xi, yi, 0)); + if (ind2 < 0) { + continue; // Boundary point + } + + if (z == 0) { + ind2 += n2d; + } + + // 3D fields on this cell + for (int j = 0; j < n3d; j++) { + const PetscInt col = ind2 + j; + if (col >= Istart && col < Iend) { + d_nnz_map3d[row].insert(col); + } else { + o_nnz_map3d[row].insert(col); + } + } + } + } + } + } + } + + d_nnz.reserve(nlocal); + d_nnz.reserve(nlocal); + + for (int i = 0; i < nlocal; ++i) { + // Assume all elements in the z direction are potentially coupled + d_nnz.emplace_back((d_nnz_map3d[i].size() * mesh->LocalNz) + + d_nnz_map2d[i].size()); + o_nnz.emplace_back((o_nnz_map3d[i].size() * mesh->LocalNz) + + o_nnz_map2d[i].size()); + } + } + + output_progress.write("Pre-allocating Jacobian\n"); + // Pre-allocate + MatMPIAIJSetPreallocation(Jfd, 0, d_nnz.data(), 0, o_nnz.data()); + MatSeqAIJSetPreallocation(Jfd, 0, d_nnz.data()); + MatSetUp(Jfd); + MatSetOption(Jfd, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_TRUE); + + ////////////////////////////////////////////////// + // Mark non-zero entries + + output_progress.write("Marking non-zero Jacobian entries\n"); + PetscScalar const val = 1.0; + for (int x = mesh->xstart; x <= mesh->xend; x++) { + for (int y = mesh->ystart; y <= mesh->yend; y++) { + + const int ind0 = ROUND(index(x, y, 0)); + + // 2D fields + for (int i = 0; i < n2d; i++) { + const PetscInt row = ind0 + i; + + // Loop through each point in the stencil + for (const auto& [x_off, y_off] : xy_offsets) { + const int xi = x + x_off; + const int yi = y + y_off; + if ((xi < 0) || (yi < 0) || (xi >= mesh->LocalNx) + || (yi >= mesh->LocalNy)) { + continue; + } + + int const ind2 = ROUND(index(xi, yi, 0)); + if (ind2 < 0) { + continue; // A boundary point + } + + // Depends on all variables on this cell + for (int j = 0; j < n2d; j++) { + PetscInt const col = ind2 + j; + PetscCall(MatSetValues(Jfd, 1, &row, 1, &col, &val, INSERT_VALUES)); + } + } + } + // 3D fields + for (int z = 0; z < mesh->LocalNz; z++) { + int const ind = ROUND(index(x, y, z)); + + for (int i = 0; i < n3d; i++) { + PetscInt row = ind + i; + if (z == 0) { + row += n2d; + } + + // Depends on 2D fields + for (int j = 0; j < n2d; j++) { + PetscInt const col = ind0 + j; + PetscCall(MatSetValues(Jfd, 1, &row, 1, &col, &val, INSERT_VALUES)); + } + + // Star pattern + for (const auto& [x_off, y_off] : xy_offsets) { + int xi = x + x_off; + int yi = y + y_off; + + if ((xi < 0) || (yi < 0) || (xi >= mesh->LocalNx) + || (yi >= mesh->LocalNy)) { + continue; + } + for (int zi = 0; zi < mesh->LocalNz; ++zi) { + int ind2 = ROUND(index(xi, yi, zi)); + if (ind2 < 0) { + continue; // Boundary point + } + + if (z == 0) { + ind2 += n2d; + } + + // 3D fields on this cell + for (int j = 0; j < n3d; j++) { + PetscInt const col = ind2 + j; + int ierr = MatSetValues(Jfd, 1, &row, 1, &col, &val, INSERT_VALUES); + + if (ierr != 0) { + output.write("ERROR: {} {} : ({}, {}) -> ({}, {}) : {} -> {}\n", + row, x, y, xi, yi, ind2, ind2 + n3d - 1); + } + CHKERRQ(ierr); + } + } + } + } + } + } + } + + // Finished marking non-zero entries + + output_progress.write("Assembling Jacobian matrix\n"); + + // Assemble Matrix + MatAssemblyBegin(Jfd, MAT_FINAL_ASSEMBLY); + MatAssemblyEnd(Jfd, MAT_FINAL_ASSEMBLY); + + { + // Test if the matrix is symmetric + // Values are 0 or 1 so tolerance (1e-5) shouldn't matter + PetscBool symmetric; + PetscCall(MatIsSymmetric(Jfd, 1e-5, &symmetric)); + if (!symmetric) { + output_warn.write("Jacobian pattern is not symmetric\n"); + } + } + + // The above can miss entries around the X-point branch cut: + // The diagonal terms are complicated because moving in X then Y + // is different from moving in Y then X at the X-point. + // Making sure the colouring matrix is symmetric does not + // necessarily give the correct stencil but may help. + if ((*options)["force_symmetric_coloring"] + .doc("Modifies coloring matrix to force it to be symmetric") + .withDefault(false)) { + Mat Jfd_T; + MatCreateTranspose(Jfd, &Jfd_T); + MatAXPY(Jfd, 1, Jfd_T, DIFFERENT_NONZERO_PATTERN); + } + + output_progress.write("Creating Jacobian coloring\n"); + updateColoring(); - if (J_slowfd != 0U) { - output_info.write("[{:d}] writing J in binary to data/Jrhs_dense.dat...\n", rank); - ierr = PetscViewerBinaryOpen(comm, "data/Jrhs_dense.dat", FILE_MODE_WRITE, &viewer); - CHKERRQ(ierr); } else { - output_info.write("[{:d}] writing J in binary to data/Jrhs_sparse.dat...\n", rank); - ierr = - PetscViewerBinaryOpen(comm, "data/Jrhs_sparse.dat", FILE_MODE_WRITE, &viewer); - CHKERRQ(ierr); + // Brute force calculation + // There is usually no reason to use this, except as a check of + // the coloring calculation. + + MatCreateAIJ( + BoutComm::get(), nlocal, nlocal, // Local sizes + PETSC_DETERMINE, PETSC_DETERMINE, // Global sizes + 3, // Number of nonzero entries in diagonal portion of local submatrix + nullptr, + 0, // Number of nonzeros per row in off-diagonal portion of local submatrix + nullptr, &Jfd); + + if (matrix_free_operator) { + SNESSetJacobian(snes, Jmf, Jfd, SNESComputeJacobianDefault, this); + } else { + SNESSetJacobian(snes, Jfd, Jfd, SNESComputeJacobianDefault, this); + } + + MatSetOption(Jfd, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE); } - ierr = MatView(J, viewer); - CHKERRQ(ierr); - ierr = PetscViewerDestroy(&viewer); - CHKERRQ(ierr); } - ierr = PetscLogEventEnd(init_event, 0, 0, 0, 0); - CHKERRQ(ierr); - - PetscFunctionReturn(0); + // Get runtime options + lib.setOptionsFromInputFile(ts); + + { + // Some reporting + TSType tstype; + TSGetType(ts, &tstype); + output_info.write("TS Type : {}\n", tstype); + TSAdaptType adapttype; + TSAdaptGetType(adapt, &adapttype); + output_info.write("TS Adapt Type : {}\n", adapttype); + if (ts_type != TSSUNDIALS) { + SNESType snestype; + SNESGetType(snes, &snestype); + output_info.write("SNES Type : {}\n", snestype); + KSPType ksptype; + KSPGetType(ksp, &ksptype); + if (ksptype) { + output_info.write("KSP Type : {}\n", ksptype); + } + } + PCType pctype; + PCGetType(pc, &pctype); + if (pctype) { + output_info.write("PC Type : {}\n", pctype); + } + } + return 0; } -/************************************************************************** - * Run - Advance time - **************************************************************************/ - +// Starts the time integrator PetscErrorCode PetscSolver::run() { - // Set when the next call to monitor is desired next_output = simtime + getOutputTimestep(); PetscFunctionBegin; - if (this->output_flag) { - prev_linear_its = 0; - bout_snes_time = bout::globals::mpi->MPI_Wtime(); - } - + // Run the PETSc time integrator + // The PetscMonitor function is responsible for regular outputs CHKERRQ(TSSolve(ts, u)); - // Gawd, everything is a hack - if ((this->output_flag != 0U) and (BoutComm::rank() == 0)) { - Output petsc_info(output_name); - // Don't write to stdout - petsc_info.disable(); - petsc_info.write("SNES Iteration, KSP Iterations, Wall Time, Norm\n"); - for (const auto& info : snes_list) { - petsc_info.write("{:d}, {:d}, {:e}, {:e}\n", info.it, info.linear_its, info.time, - info.norm); - } - } - PetscFunctionReturn(0); } -/************************************************************************** - * RHS function - **************************************************************************/ - -PetscErrorCode PetscSolver::rhs(TS UNUSED(ts), BoutReal t, Vec udata, Vec dudata) { +// Evaluate the user-supplied RHS function +// This method is called from the static PETSc callback functions +PetscErrorCode PetscSolver::rhs(BoutReal t, Vec udata, Vec dudata, bool linear) { TRACE("Running RHS: PetscSolver::rhs({:e})", t); - const BoutReal* udata_array; - BoutReal* dudata_array; + simtime = t; PetscFunctionBegin; // Load state from PETSc + const BoutReal* udata_array; VecGetArrayRead(udata, &udata_array); load_vars(const_cast(udata_array)); VecRestoreArrayRead(udata, &udata_array); // Call RHS function - run_rhs(t); + run_rhs(t, linear); // Save derivatives to PETSc + BoutReal* dudata_array; VecGetArray(dudata, &dudata_array); save_derivs(dudata_array); VecRestoreArray(dudata, &dudata_array); @@ -623,19 +915,21 @@ PetscErrorCode PetscSolver::rhs(TS UNUSED(ts), BoutReal t, Vec udata, Vec dudata PetscFunctionReturn(0); } -/************************************************************************** - * Preconditioner function - **************************************************************************/ +PetscErrorCode PetscSolver::formFunction(Vec U, Vec F) { + PetscFunctionBegin; + PetscCall(rhs(simtime, U, F, true)); // Can be linearised for coloring -PetscErrorCode PetscSolver::pre(PC UNUSED(pc), Vec x, Vec y) { + // shift * U - dU/dt + PetscCall(VecAXPBY(F, shift, -1.0, U)); + PetscFunctionReturn(0); +} + +// Matrix-free preconditioner function +PetscErrorCode PetscSolver::pre(Vec x, Vec y) { TRACE("PetscSolver::pre()"); BoutReal* data; - if (diagnose) { - output << "Preconditioning" << endl; - } - // Load state VecGetArray(state, &data); load_vars(data); @@ -654,355 +948,66 @@ PetscErrorCode PetscSolver::pre(PC UNUSED(pc), Vec x, Vec y) { save_derivs(data); VecRestoreArray(y, &data); - // Petsc's definition of Jacobian differs by a factor from Sundials' - PetscErrorCode ierr = VecScale(y, shift); - CHKERRQ(ierr); + // Petsc's definition of Jacobian differs by a factor from SUNDIALS' + // PETSc solves (scale + J)^-1 + // SUNDIALS solves (I + gamma J)^-1 + PetscCall(VecScale(y, shift)); return 0; } -/************************************************************************** - * User-supplied Jacobian function J(state) * x = y - **************************************************************************/ - -PetscErrorCode PetscSolver::jac(Vec x, Vec y) { - TRACE("PetscSolver::jac()"); - - BoutReal* data; - - if (diagnose) { - output << "Jacobian evaluation\n"; - } - - // Load state - VecGetArray(state, &data); - load_vars(data); - VecRestoreArray(state, &data); - - // Load vector to be operated on into F_vars - VecGetArray(x, &data); - load_derivs(data); - VecRestoreArray(x, &data); - - // Call the Jacobian function - runJacobian(ts_time); - - // Save the solution from time derivatives - VecGetArray(y, &data); - save_derivs(data); - VecRestoreArray(y, &data); - - // y = a * x - y - PetscErrorCode ierr = VecAXPBY(y, shift, -1.0, x); - CHKERRQ(ierr); - - return 0; -} - -/************************************************************************** - * Static functions which can be used for PETSc callbacks - **************************************************************************/ - -PetscErrorCode solver_f(TS ts, BoutReal t, Vec globalin, Vec globalout, void* f_data) { - PetscFunctionBegin; - auto* s = static_cast(f_data); - PetscLogEventBegin(s->solver_event, 0, 0, 0, 0); - s->rhs(ts, t, globalin, globalout); - PetscLogEventEnd(s->solver_event, 0, 0, 0, 0); - PetscFunctionReturn(0); -} - -/* - FormIFunction = Udot - RHSFunction -*/ -PetscErrorCode solver_if(TS ts, BoutReal t, Vec globalin, Vec globalindot, Vec globalout, - void* f_data) { - PetscErrorCode ierr; - - PetscFunctionBegin; - ierr = solver_f(ts, t, globalin, globalout, f_data); - CHKERRQ(ierr); - - ierr = VecAYPX(globalout, -1.0, globalindot); - CHKERRQ(ierr); // globalout = globalindot + (-1)globalout - PetscFunctionReturn(0); -} - -#if PETSC_VERSION_GE(3, 5, 0) -PetscErrorCode solver_rhsjacobian(TS UNUSED(ts), BoutReal UNUSED(t), Vec UNUSED(globalin), - Mat J, Mat Jpre, void* UNUSED(f_data)) { - PetscErrorCode ierr; - - PetscFunctionBegin; - ierr = MatAssemblyBegin(Jpre, MAT_FINAL_ASSEMBLY); - CHKERRQ(ierr); - ierr = MatAssemblyEnd(Jpre, MAT_FINAL_ASSEMBLY); - CHKERRQ(ierr); - if (J != Jpre) { - ierr = MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY); - CHKERRQ(ierr); - ierr = MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY); - CHKERRQ(ierr); - } - 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 ierr; - - PetscFunctionBegin; - ierr = MatAssemblyBegin(*Jpre, MAT_FINAL_ASSEMBLY); - CHKERRQ(ierr); - ierr = MatAssemblyEnd(*Jpre, MAT_FINAL_ASSEMBLY); - CHKERRQ(ierr); - if (*J != *Jpre) { - ierr = MatAssemblyBegin(*J, MAT_FINAL_ASSEMBLY); - CHKERRQ(ierr); - ierr = MatAssemblyEnd(*J, MAT_FINAL_ASSEMBLY); - CHKERRQ(ierr); - } - PetscFunctionReturn(0); -} -#endif - -/* - solver_ijacobian - Compute IJacobian = dF/dU + a dF/dUdot - a dummy matrix used for pc=none -*/ -#if PETSC_VERSION_GE(3, 5, 0) -PetscErrorCode solver_ijacobian(TS ts, BoutReal t, Vec globalin, Vec UNUSED(globalindot), - PetscReal a, Mat J, Mat Jpre, void* f_data) { - PetscErrorCode ierr; - - PetscFunctionBegin; - ierr = solver_rhsjacobian(ts, t, globalin, J, Jpre, f_data); - CHKERRQ(ierr); - - ////// Save data for preconditioner - auto* solver = static_cast(f_data); - - if (solver->diagnose) { - output << "Saving state, t = " << t << ", a = " << a << endl; - } - - solver->shift = a; // Save the shift 'a' - solver->state = globalin; // Save system state - solver->ts_time = t; - - PetscFunctionReturn(0); -} -#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) { - PetscErrorCode ierr; - - PetscFunctionBegin; - ierr = solver_rhsjacobian(ts, t, globalin, J, Jpre, str, (void*)f_data); - CHKERRQ(ierr); +void PetscSolver::updateColoring() { + // Re-calculate the coloring + MatColoring coloring{nullptr}; + MatColoringCreate(Jfd, &coloring); + MatColoringSetType(coloring, MATCOLORINGGREEDY); + MatColoringSetFromOptions(coloring); - ////// Save data for preconditioner - PetscSolver* solver = (PetscSolver*)f_data; + // Calculate new index sets + ISColoring iscoloring{nullptr}; + MatColoringApply(coloring, &iscoloring); + MatColoringDestroy(&coloring); - if (solver->diagnose) { - output << "Saving state, t = " << t << ", a = " << a << endl; + // Replace the old coloring with the new one + MatFDColoringDestroy(&fdcoloring); + MatFDColoringCreate(Jfd, iscoloring, &fdcoloring); + if (ts_type != TSSUNDIALS) { + // Use the SNES function that is defined by the TS method + // SNESTSFormFunction is defined in PETSc ts.c + // The ctx pointer should be the TS object + // + // Note: The function type casting here is horrible but necessary + MatFDColoringSetFunction(fdcoloring, bout::cast_MatFDColoringFn(SNESTSFormFunction), + ts); + } else { + // SNESTSFormFunction is not available for SUNDIALS. + // This solver_form_function needs to know the shift + // (SUNDIALS' gamma) that we capture in solver_ijacobian_color. + MatFDColoringSetFunction(fdcoloring, bout::cast_MatFDColoringFn(solver_form_function), + this); } - - solver->shift = a; // Save the shift 'a' - solver->state = globalin; // Save system state - solver->ts_time = t; - - PetscFunctionReturn(0); -} + MatFDColoringSetFromOptions(fdcoloring); + MatFDColoringSetUp(Jfd, iscoloring, fdcoloring); + ISColoringDestroy(&iscoloring); + + // Replace the CTX pointer in SNES Jacobian + if (ts_type == TSSUNDIALS) { +#if PETSC_HAVE_SUNDIALS2 + // The SUNDIALS interface calls TSGetIJacobian + // https://www.mcs.anl.gov/petsc/petsc-3.14/src/ts/impls/implicit/sundials/sundials.c + // This sets the "TSMatFDColoring" property on the Jacobian, that is used in TSComputeIJacobianDefaultColor + PetscObjectCompose((PetscObject)Jfd, "TSMatFDColoring", (PetscObject)fdcoloring); + // Call a wrapper function that stores the shift in the PetscSolver + TSSetIJacobian(ts, Jfd, Jfd, solver_ijacobian_color, this); #endif - -/* - solver_ijacobianfd - Compute IJacobian = dF/dU + a dF/dUdot using finite deference - not implemented yet -*/ -#if PETSC_VERSION_GE(3, 5, 0) -PetscErrorCode solver_ijacobianfd(TS ts, BoutReal t, Vec globalin, - Vec UNUSED(globalindot), PetscReal UNUSED(a), Mat J, - Mat Jpre, void* f_data) { - PetscErrorCode ierr; - - PetscFunctionBegin; - ierr = solver_rhsjacobian(ts, t, globalin, J, Jpre, f_data); - CHKERRQ(ierr); - //*Jpre + a - PetscFunctionReturn(0); -} -#else -PetscErrorCode solver_ijacobianfd(TS ts, BoutReal t, Vec globalin, Vec globalindot, - PetscReal a, Mat* J, Mat* Jpre, MatStructure* str, - void* f_data) { - PetscErrorCode ierr; - - PetscFunctionBegin; - ierr = solver_rhsjacobian(ts, t, globalin, J, Jpre, str, (void*)f_data); - CHKERRQ(ierr); - //*Jpre + a - PetscFunctionReturn(0); -} -#endif -//----------------------------------------- - -PetscErrorCode PhysicsSNESApply(SNES snes, Vec x) { - PetscErrorCode ierr; - Vec F, Fout; - PetscReal fnorm = 0., foutnorm = 0., dot = 0.; - KSP ksp; - PC pc; - Mat A, B; - - PetscFunctionBegin; - ierr = SNESGetJacobian(snes, &A, &B, nullptr, nullptr); - CHKERRQ(ierr); -#if PETSC_VERSION_GE(3, 5, 0) - ierr = SNESComputeJacobian(snes, x, A, B); - CHKERRQ(ierr); -#else - MatStructure diff = DIFFERENT_NONZERO_PATTERN; - ierr = SNESComputeJacobian(snes, x, &A, &B, &diff); - CHKERRQ(ierr); -#endif - ierr = SNESGetKSP(snes, &ksp); - CHKERRQ(ierr); - ierr = KSPGetPC(ksp, &pc); - CHKERRQ(ierr); - ierr = SNESGetFunction(snes, &F, nullptr, nullptr); - CHKERRQ(ierr); - ierr = SNESComputeFunction(snes, x, F); - CHKERRQ(ierr); - ierr = SNESGetSolutionUpdate(snes, &Fout); - CHKERRQ(ierr); - - ierr = PCApply(pc, F, Fout); - CHKERRQ(ierr); - ierr = VecNorm(Fout, NORM_2, &foutnorm); - CHKERRQ(ierr); - ierr = VecAXPY(x, -1., Fout); - CHKERRQ(ierr); - ierr = SNESComputeFunction(snes, x, F); - CHKERRQ(ierr); - ierr = VecNorm(F, NORM_2, &fnorm); - CHKERRQ(ierr); - ierr = VecDot(F, Fout, &dot); - CHKERRQ(ierr); - output_info << " (Debug) function norm: " << fnorm << ", P(f) norm " << foutnorm - << ", F \\cdot Fout " << dot << " "; -#if PETSC_VERSION_GE(3, 5, 0) - Vec func; - ierr = SNESGetFunction(snes, &func, nullptr, nullptr); - CHKERRQ(ierr); - ierr = VecNorm(func, NORM_2, &fnorm); - CHKERRQ(ierr); -#else - ierr = SNESSetFunctionNorm(snes, fnorm); - CHKERRQ(ierr); -#endif - ierr = SNESMonitor(snes, 0, fnorm); - CHKERRQ(ierr); - - PetscFunctionReturn(0); -} - -PetscErrorCode PhysicsPCApply(PC pc, Vec x, Vec y) { - int ierr; - - // Get the context - PetscSolver* s; - ierr = PCShellGetContext(pc, reinterpret_cast(&s)); - CHKERRQ(ierr); - - PetscFunctionReturn(s->pre(pc, x, y)); -} - -PetscErrorCode PhysicsJacobianApply(Mat J, Vec x, Vec y) { - // Get the context - PetscSolver* s; - int ierr = MatShellGetContext(J, reinterpret_cast(&s)); - CHKERRQ(ierr); - PetscFunctionReturn(s->jac(x, y)); -} - -PetscErrorCode PetscMonitor(TS ts, PetscInt UNUSED(step), PetscReal t, Vec X, void* ctx) { - PetscErrorCode ierr; - auto* s = static_cast(ctx); - PetscReal tfinal, dt; - Vec interpolatedX; - const PetscScalar* x; - static int i = 0; - - PetscFunctionBegin; - ierr = TSGetTimeStep(ts, &dt); - CHKERRQ(ierr); - -#if PETSC_VERSION_GE(3, 8, 0) - ierr = TSGetMaxTime(ts, &tfinal); - CHKERRQ(ierr); -#else - ierr = TSGetDuration(ts, nullptr, &tfinal); - CHKERRQ(ierr); -#endif - - /* Duplicate the solution vector X into a work vector */ - ierr = VecDuplicate(X, &interpolatedX); - CHKERRQ(ierr); - while (s->next_output <= t && s->next_output <= tfinal) { - if (s->interpolate) { - ierr = TSInterpolate(ts, s->next_output, interpolatedX); - CHKERRQ(ierr); - } - - /* Place the interpolated values into the global variables */ - ierr = VecGetArrayRead(interpolatedX, &x); - CHKERRQ(ierr); - s->load_vars(const_cast(x)); - ierr = VecRestoreArrayRead(interpolatedX, &x); - CHKERRQ(ierr); - - if (s->call_monitors(simtime, i++, s->getNumberOutputSteps())) { - PetscFunctionReturn(1); + } else { + if (matrix_free_operator) { + // Use matrix-free calculation for operator, finite difference for preconditioner + SNESSetJacobian(snes, Jmf, Jfd, SNESComputeJacobianDefaultColor, fdcoloring); + } else { + SNESSetJacobian(snes, Jfd, Jfd, SNESComputeJacobianDefaultColor, fdcoloring); } - - s->next_output += s->getOutputTimestep(); - simtime = s->next_output; - } - - /* Done with vector, so destroy it */ - ierr = VecDestroy(&interpolatedX); - CHKERRQ(ierr); - - PetscFunctionReturn(0); -} - -PetscErrorCode PetscSNESMonitor(SNES snes, PetscInt its, PetscReal norm, void* ctx) { - PetscErrorCode ierr; - PetscInt linear_its = 0; - BoutReal tmp = .0; - snes_info row; - auto* s = static_cast(ctx); - - PetscFunctionBegin; - - if (!its) { - s->prev_linear_its = 0; } - ierr = SNESGetLinearSolveIterations(snes, &linear_its); - CHKERRQ(ierr); - tmp = bout::globals::mpi->MPI_Wtime(); - - row.it = its; - s->prev_linear_its = row.linear_its = linear_its - s->prev_linear_its; - row.time = tmp - s->bout_snes_time; - row.norm = norm; - - s->snes_list.push_back(row); - - PetscFunctionReturn(0); } #endif diff --git a/src/solver/impls/petsc/petsc.hxx b/src/solver/impls/petsc/petsc.hxx index 686a7c6242..78f7d1a1e4 100644 --- a/src/solver/impls/petsc/petsc.hxx +++ b/src/solver/impls/petsc/petsc.hxx @@ -1,11 +1,10 @@ /************************************************************************** * Interface to PETSc solver - * NOTE: This class needs tidying, generalising to use FieldData interface * ************************************************************************** - * Copyright 2010 B.D.Dudson, S.Farley, M.V.Umansky, X.Q.Xu + * Copyright 2010 - 2025 BOUT++ contributors * - * Contact: Ben Dudson, bd512@york.ac.uk + * Contact: Ben Dudson, dudson2@llnl.gov * * This file is part of BOUT++. * @@ -48,6 +47,10 @@ class PetscSolver; #include #include +#include +#include +#include +#include #include @@ -55,35 +58,6 @@ namespace { RegisterSolver registersolverpetsc("petsc"); } -using BoutReal = PetscScalar; -#define OPT_SIZE 40 - -using rhsfunc = int (*)(BoutReal); - -extern BoutReal simtime; - -/// Monitor function called on every internal timestep -extern PetscErrorCode PetscMonitor(TS, PetscInt, PetscReal, Vec, void* ctx); -/// Monitor function for SNES -extern PetscErrorCode PetscSNESMonitor(SNES, PetscInt, PetscReal, void* ctx); - -/// Compute IJacobian = dF/dU + a dF/dUdot - a dummy matrix used for pc=none -#if PETSC_VERSION_GE(3, 5, 0) -extern PetscErrorCode solver_ijacobian(TS, PetscReal, Vec, Vec, PetscReal, Mat, Mat, - void*); -#else -extern PetscErrorCode solver_ijacobian(TS, PetscReal, Vec, Vec, PetscReal, Mat*, Mat*, - MatStructure*, void*); -#endif - -/// Data for SNES -struct snes_info { - PetscInt it; - PetscInt linear_its; - PetscReal time; - PetscReal norm; -}; - class PetscSolver : public Solver { public: PetscSolver(Options* opts = nullptr); @@ -95,24 +69,22 @@ public: // These functions used internally (but need to be public) /// Wrapper for the RHS function - PetscErrorCode rhs(TS ts, PetscReal t, Vec globalin, Vec globalout); + PetscErrorCode rhs(BoutReal t, Vec udata, Vec dudata, bool linear); + /// Residual calculation. + PetscErrorCode formFunction(Vec U, Vec F); /// Wrapper for the preconditioner - PetscErrorCode pre(PC pc, Vec x, Vec y); - /// Wrapper for the Jacobian function - PetscErrorCode jac(Vec x, Vec y); + PetscErrorCode pre(Vec x, Vec y); // Call back functions that need to access internal state friend PetscErrorCode PetscMonitor(TS, PetscInt, PetscReal, Vec, void* ctx); - friend PetscErrorCode PetscSNESMonitor(SNES, PetscInt, PetscReal, void* ctx); -#if PETSC_VERSION_GE(3, 5, 0) - friend PetscErrorCode solver_ijacobian(TS, PetscReal, Vec, Vec, PetscReal, Mat, Mat, - void*); -#else - friend PetscErrorCode solver_ijacobian(TS, PetscReal, Vec, Vec, PetscReal, Mat*, Mat*, - MatStructure*, void*); -#endif - PetscLogEvent solver_event, loop_event, init_event; + friend PetscErrorCode solver_ijacobian(TS, BoutReal, Vec, Vec, PetscReal shift, Mat J, + Mat Jpre, void* ctx); + + // Wrapper around TSComputeIJacobianDefaultColor that saves the shift + // This is used to compute the Jacobian using coloring with SUNDIALS TS method. + friend PetscErrorCode solver_ijacobian_color(TS ts, PetscReal t, Vec U, Vec Udot, + PetscReal shift, Mat J, Mat B, void* ctx); private: BoutReal shift; ///< Shift (alpha) parameter from TS @@ -121,28 +93,45 @@ private: PetscLib lib; ///< Handles initialising, finalising PETSc - Vec u{nullptr}; ///< PETSc solution vector - TS ts{nullptr}; ///< PETSc timestepper object - Mat J{nullptr}; ///< RHS Jacobian - Mat Jmf{nullptr}; - MatFDColoring matfdcoloring{nullptr}; - - bool diagnose; ///< If true, print some information about current stage + Vec u{nullptr}; ///< PETSc solution vector + TS ts{nullptr}; ///< PETSc timestepper object + SNES snes{nullptr}; ///< PETSc nonlinear solver object + KSP ksp{nullptr}; ///< PETSc linear solver + Mat Jmf{nullptr}; ///< Matrix Free Jacobian + Mat Jfd{nullptr}; ///< Finite Difference Jacobian + MatFDColoring fdcoloring{nullptr}; ///< Matrix coloring context BoutReal next_output; ///< When the monitor should be called next - PetscBool interpolate{PETSC_TRUE}; ///< Whether to interpolate or not + bool interpolate; ///< Interpolate to regular times? + + bool diagnose; ///< If true, print some information about current stage + bool user_precon; ///< Use user-supplied preconditioning function? + + BoutReal atol; ///< Absolute tolerance + BoutReal rtol; ///< Relative tolerance + BoutReal stol; ///< Convergence tolerance + + int maxnl; ///< Maximum nonlinear iterations per SNES solve + int maxf; ///< Maximum number of function evaluations allowed in the solver (default: 10000) + int maxl; ///< Maximum linear iterations + + std::string ts_type; ///< PETSc TS time solver type + std::string adapt_type; ///< TSAdaptType timestep adaptation + std::string snes_type; ///< PETSc SNES nonlinear solver type + std::string ksp_type; ///< PETSc KSP linear solver type + std::string pc_type; ///< Preconditioner type + std::string pc_hypre_type; ///< Hypre preconditioner type + std::string line_search_type; ///< Line search type + + bool matrix_free; ///< Use matrix free Jacobian + bool matrix_free_operator; ///< Use matrix free Jacobian in the operator? + int lag_jacobian; ///< Re-use Jacobian + bool use_coloring; ///< Use matrix coloring + void updateColoring(); ///< Updates the coloring using Jfd - char output_name[PETSC_MAX_PATH_LEN]; - PetscBool output_flag{PETSC_FALSE}; - PetscInt prev_linear_its; - BoutReal bout_snes_time{0.0}; - std::vector snes_list; + bool kspsetinitialguessnonzero; ///< Set initial guess to non-zero - bool adaptive; ///< Use adaptive timestepping - bool use_precon, use_jacobian; - BoutReal abstol, reltol; - bool adams_moulton; BoutReal start_timestep; int mxstep; }; diff --git a/src/solver/impls/snes/snes.cxx b/src/solver/impls/snes/snes.cxx index 15099f9e2a..820f2cbebb 100644 --- a/src/solver/impls/snes/snes.cxx +++ b/src/solver/impls/snes/snes.cxx @@ -57,6 +57,7 @@ class ColoringStencil { } }; +namespace { /* * PETSc callback function, which evaluates the nonlinear * function to be solved by SNES. @@ -64,7 +65,7 @@ class ColoringStencil { * This function assumes the context void pointer is a pointer * to an SNESSolver object. */ -static PetscErrorCode FormFunction(SNES UNUSED(snes), Vec x, Vec f, void* ctx) { +PetscErrorCode FormFunction(SNES UNUSED(snes), Vec x, Vec f, void* ctx) { return static_cast(ctx)->snes_function(x, f, false); } @@ -73,7 +74,7 @@ static PetscErrorCode FormFunction(SNES UNUSED(snes), Vec x, Vec f, void* ctx) { * * This function can be a linearised form of FormFunction */ -static PetscErrorCode FormFunctionForDifferencing(void* ctx, Vec x, Vec f) { +PetscErrorCode FormFunctionForDifferencing(void* ctx, Vec x, Vec f) { return static_cast(ctx)->snes_function(x, f, true); } @@ -82,21 +83,19 @@ static PetscErrorCode FormFunctionForDifferencing(void* ctx, Vec x, Vec f) { * * This can be a linearised and simplified form of FormFunction */ -static PetscErrorCode FormFunctionForColoring(void* UNUSED(snes), Vec x, Vec f, - void* ctx) { +PetscErrorCode FormFunctionForColoring(void* UNUSED(snes), Vec x, Vec f, void* ctx) { return static_cast(ctx)->snes_function(x, f, true); } -static PetscErrorCode snesPCapply(PC pc, Vec x, Vec y) { - int ierr; - +PetscErrorCode snesPCapply(PC pc, Vec x, Vec y) { // Get the context SNESSolver* s; - ierr = PCShellGetContext(pc, reinterpret_cast(&s)); + int ierr = PCShellGetContext(pc, reinterpret_cast(&s)); CHKERRQ(ierr); PetscFunctionReturn(s->precon(x, y)); } +} // namespace SNESSolver::SNESSolver(Options* opts) : Solver(opts), @@ -115,6 +114,9 @@ SNESSolver::SNESSolver(Options* opts) .doc("Convergence tolerance in terms of the norm of the change in " "the solution between steps") .withDefault(1e-8)), + maxf((*options)["maxf"] + .doc("Maximum number of function evaluations per SNES solve") + .withDefault(10000)), maxits((*options)["max_nonlinear_iterations"] .doc("Maximum number of nonlinear iterations per SNES solve") .withDefault(50)), @@ -125,14 +127,22 @@ SNESSolver::SNESSolver(Options* opts) .doc("Iterations above which the next timestep is reduced") .withDefault(static_cast(maxits * 0.8))), timestep_factor_on_failure((*options)["timestep_factor_on_failure"] - .doc("Multiply timestep on convergence failure") - .withDefault(0.5)), - timestep_factor_on_upper_its((*options)["timestep_factor_on_upper_its"] - .doc("Multiply timestep if iterations exceed upper_its") - .withDefault(0.9)), - timestep_factor_on_lower_its((*options)["timestep_factor_on_lower_its"] - .doc("Multiply timestep if iterations are below lower_its") - .withDefault(1.4)), + .doc("Multiply timestep on convergence failure") + .withDefault(0.5)), + timestep_factor_on_upper_its( + (*options)["timestep_factor_on_upper_its"] + .doc("Multiply timestep if iterations exceed upper_its") + .withDefault(0.9)), + timestep_factor_on_lower_its( + (*options)["timestep_factor_on_lower_its"] + .doc("Multiply timestep if iterations are below lower_its") + .withDefault(1.4)), + pid_controller( + (*options)["pid_controller"].doc("Use PID controller?").withDefault(false)), + target_its((*options)["target_its"].doc("Target snes iterations").withDefault(7)), + kP((*options)["kP"].doc("Proportional PID parameter").withDefault(0.7)), + kI((*options)["kI"].doc("Integral PID parameter").withDefault(0.3)), + kD((*options)["kD"].doc("Derivative PID parameter").withDefault(0.2)), diagnose( (*options)["diagnose"].doc("Print additional diagnostics").withDefault(false)), diagnose_failures((*options)["diagnose_failures"] @@ -340,6 +350,7 @@ int SNESSolver::init() { // Set size of Matrix on each processor to nlocal x nlocal MatCreate(BoutComm::get(), &Jfd); + MatSetOption(Jfd, MAT_KEEP_NONZERO_PATTERN, PETSC_TRUE); MatSetSizes(Jfd, nlocal, nlocal, PETSC_DETERMINE, PETSC_DETERMINE); MatSetFromOptions(Jfd); // Determine which row/columns of the matrix are locally owned @@ -365,8 +376,8 @@ int SNESSolver::init() { auto n_cross = (*options)["stencil:cross"] .doc("Extent of stencil (cross)") .withDefault(0); - //Set n_taxi 2 if nothing else is set - //Probably a better way to do this + // Set n_taxi 2 if nothing else is set + // Probably a better way to do this if (n_square == 0 && n_taxi == 0 && n_cross == 0) { output_info.write("Setting solver:stencil:taxi = 2\n"); n_taxi = 2; @@ -473,7 +484,7 @@ int SNESSolver::init() { d_nnz.reserve(nlocal); for (int i = 0; i < nlocal; ++i) { - //Assume all elements in the z direction are potentially coupled + // Assume all elements in the z direction are potentially coupled d_nnz.emplace_back(d_nnz_map3d[i].size() * mesh->LocalNz + d_nnz_map2d[i].size()); o_nnz.emplace_back(o_nnz_map3d[i].size() * mesh->LocalNz @@ -586,9 +597,22 @@ int SNESSolver::init() { MatAssemblyBegin(Jfd, MAT_FINAL_ASSEMBLY); MatAssemblyEnd(Jfd, MAT_FINAL_ASSEMBLY); - //The above will probably miss some non-zero entries at process boundaries - //Making sure the colouring matrix is symmetric will in some/all(?) - //of the missing non-zeros + { + // Test if the matrix is symmetric + // Values are 0 or 1 so tolerance (1e-5) shouldn't matter + PetscBool symmetric; + ierr = MatIsSymmetric(Jfd, 1e-5, &symmetric); + CHKERRQ(ierr); + if (!symmetric) { + output_warn.write("Jacobian pattern is not symmetric\n"); + } + } + + // The above can miss entries around the X-point branch cut: + // The diagonal terms are complicated because moving in X then Y + // is different from moving in Y then X at the X-point. + // Making sure the colouring matrix is symmetric does not + // necessarily give the correct stencil but may help. if ((*options)["force_symmetric_coloring"] .doc("Modifies coloring matrix to force it to be symmetric") .withDefault(false)) { @@ -632,14 +656,21 @@ int SNESSolver::init() { // Note: If the 'Amat' Jacobian is matrix free, SNESComputeJacobian // always updates its reference 'u' vector every nonlinear iteration SNESSetLagJacobian(snes, lag_jacobian); - // Set Jacobian and preconditioner to persist across time steps - SNESSetLagJacobianPersists(snes, PETSC_TRUE); - SNESSetLagPreconditionerPersists(snes, PETSC_TRUE); + if (pid_controller) { + nl_its_prev = target_its; + nl_its_prev2 = target_its; + SNESSetLagJacobianPersists(snes, PETSC_FALSE); + SNESSetLagPreconditionerPersists(snes, PETSC_FALSE); + } else { + // Set Jacobian and preconditioner to persist across time steps + SNESSetLagJacobianPersists(snes, PETSC_TRUE); + SNESSetLagPreconditionerPersists(snes, PETSC_TRUE); + } SNESSetLagPreconditioner(snes, 1); // Rebuild when Jacobian is rebuilt } // Set tolerances - SNESSetTolerances(snes, atol, rtol, stol, maxits, PETSC_DEFAULT); + SNESSetTolerances(snes, atol, rtol, stol, maxits, maxf); // Force SNES to take at least one nonlinear iteration. // This may prevent the solver from getting stuck in false steady state conditions @@ -843,6 +874,10 @@ int SNESSolver::run() { VecAXPBY(snes_x, -beta, (1. + beta), x1); } + if (pid_controller) { + SNESSetLagJacobian(snes, lag_jacobian); + } + // Run the solver PetscErrorCode ierr = SNESSolve(snes, nullptr, snes_x); @@ -900,6 +935,7 @@ int SNESSolver::run() { updateColoring(); jacobian_pruned = false; // Reset flag. Will be set after pruning. } + if (saved_jacobian_lag == 0) { // This triggers a Jacobian recalculation SNESGetLagJacobian(snes, &saved_jacobian_lag); @@ -1032,7 +1068,23 @@ int SNESSolver::run() { } #endif // PETSC_VERSION_GE(3,20,0) - if (looping) { + if (pid_controller) { + // Changing the timestep. + // Note: The preconditioner depends on the timestep, + // so we recalculate the jacobian and the preconditioner + // every time the timestep changes + + timestep = pid(timestep, nl_its); + + // NOTE(malamast): Do we really need this? + // Recompute Jacobian (for now) + if (saved_jacobian_lag == 0) { + SNESGetLagJacobian(snes, &saved_jacobian_lag); + SNESSetLagJacobian(snes, 1); + } + + } else { + // Consider changing the timestep. // Note: The preconditioner depends on the timestep, // so if it is not recalculated the it will be less @@ -1042,9 +1094,7 @@ int SNESSolver::run() { // Increase timestep slightly timestep *= timestep_factor_on_lower_its; - if (timestep > max_timestep) { - timestep = max_timestep; - } + timestep = std::min(timestep, max_timestep); // Note: Setting the SNESJacobianFn to NULL retains // previously set evaluation function. @@ -1078,7 +1128,7 @@ int SNESSolver::run() { if (!matrix_free) { ASSERT2(simtime >= target); - ASSERT2(simtime - dt < target); + ASSERT2(simtime - dt <= target); // Stepped over output timestep => Interpolate // snes_x is the solution at t = simtime // x0 is the solution at t = simtime - dt @@ -1360,7 +1410,10 @@ void SNESSolver::updateColoring() { // Re-calculate the coloring MatColoring coloring = NULL; MatColoringCreate(Jfd, &coloring); - MatColoringSetType(coloring, MATCOLORINGSL); + // MatColoringSetType(coloring, MATCOLORINGSL); // Serial algorithm. Better for smale-to-medium size problems. + MatColoringSetType( + coloring, MATCOLORINGGREEDY); // Parallel algorith. Better for large parallel runs + // MatColoringSetType(coloring, MATCOLORINGJP); // This didn't work MatColoringSetFromOptions(coloring); // Calculate new index sets @@ -1386,4 +1439,25 @@ void SNESSolver::updateColoring() { } } +BoutReal SNESSolver::pid(BoutReal timestep, int nl_its) { + + /* ---------- multiplicative PID factors ---------- */ + const BoutReal facP = std::pow(double(target_its) / double(nl_its), kP); + const BoutReal facI = std::pow(double(nl_its_prev) / double(nl_its), kI); + const BoutReal facD = std::pow(double(nl_its_prev) * double(nl_its_prev) + / double(nl_its) / double(nl_its_prev2), + kD); + + // clamp groth factor to avoid huge changes + const BoutReal fac = std::clamp(facP * facI * facD, 0.2, 5.0); + + /* ---------- update timestep and history ---------- */ + const BoutReal dt_new = std::min(timestep * fac, max_timestep); + + nl_its_prev2 = nl_its_prev; + nl_its_prev = nl_its; + + return dt_new; +} + #endif // BOUT_HAS_PETSC diff --git a/src/solver/impls/snes/snes.hxx b/src/solver/impls/snes/snes.hxx index cba2352582..31deae6f06 100644 --- a/src/solver/impls/snes/snes.hxx +++ b/src/solver/impls/snes/snes.hxx @@ -57,7 +57,7 @@ BOUT_ENUM_CLASS(BoutSnesEquationForm, pseudo_transient, rearranged_backward_eule class SNESSolver : public Solver { public: explicit SNESSolver(Options* opts = nullptr); - ~SNESSolver() = default; + ~SNESSolver() override = default; int init() override; int run() override; @@ -98,6 +98,7 @@ private: BoutReal atol; ///< Absolute tolerance BoutReal rtol; ///< Relative tolerance BoutReal stol; ///< Convergence tolerance + int maxf; ///< Maximum number of function evaluations allowed in the solver (default: 10000) int maxits; ///< Maximum nonlinear iterations int lower_its, upper_its; ///< Limits on iterations for timestep adjustment @@ -106,6 +107,19 @@ private: BoutReal timestep_factor_on_upper_its; BoutReal timestep_factor_on_lower_its; + ///< PID controller parameters + bool pid_controller; ///< Use PID controller? + int target_its; ///< Target number of nonlinear iterations for the PID controller. + ///< Use with caution! Not tested values. + BoutReal kP; ///< (0.6 - 0.8) Proportional parameter (main response to current step) + BoutReal kI; ///< (0.2 - 0.4) Integral parameter (smooths history of changes) + BoutReal kD; ///< (0.1 - 0.3) Derivative (dampens oscillation - optional) + + int nl_its_prev; + int nl_its_prev2; + + BoutReal pid(BoutReal timestep, int nl_its); ///< Updates the timestep + bool diagnose; ///< Output additional diagnostics bool diagnose_failures; ///< Print diagnostics on SNES failures diff --git a/src/sys/derivs.cxx b/src/sys/derivs.cxx index ee9bcbcc2c..71afe56507 100644 --- a/src/sys/derivs.cxx +++ b/src/sys/derivs.cxx @@ -70,7 +70,7 @@ Coordinates::FieldMetric DDX(const Field2D& f, CELL_LOC outloc, const std::strin ////////////// Y DERIVATIVE ///////////////// -Field3D DDY(const Field3D& f, CELL_LOC outloc, const std::string& method, +Field3D DDY(const Field3DParallel& f, CELL_LOC outloc, const std::string& method, const std::string& region) { return bout::derivatives::index::DDY(f, outloc, method, region) / f.getCoordinates(outloc)->dy; @@ -410,7 +410,7 @@ Coordinates::FieldMetric VDDY(const Field2D& v, const Field2D& f, CELL_LOC outlo } // general case -Field3D VDDY(const Field3D& v, const Field3D& f, CELL_LOC outloc, +Field3D VDDY(const Field3D& v, const Field3DParallel& f, CELL_LOC outloc, const std::string& method, const std::string& region) { return bout::derivatives::index::VDDY(v, f, outloc, method, region) / f.getCoordinates(outloc)->dy; @@ -471,7 +471,7 @@ Coordinates::FieldMetric FDDY(const Field2D& v, const Field2D& f, CELL_LOC outlo / f.getCoordinates(outloc)->dy; } -Field3D FDDY(const Field3D& v, const Field3D& f, CELL_LOC outloc, +Field3D FDDY(const Field3D& v, const Field3DParallel& f, CELL_LOC outloc, const std::string& method, const std::string& region) { return bout::derivatives::index::FDDY(v, f, outloc, method, region) / f.getCoordinates(outloc)->dy; diff --git a/src/sys/options/options_netcdf.cxx b/src/sys/options/options_netcdf.cxx index 60dfba2102..94b62f0f02 100644 --- a/src/sys/options/options_netcdf.cxx +++ b/src/sys/options/options_netcdf.cxx @@ -448,10 +448,7 @@ void NcPutAttVisitor::operator()(const std::string& value) { void writeGroup(const Options& options, NcGroup group, const std::string& time_dimension) { - for (const auto& childpair : options.getChildren()) { - const auto& name = childpair.first; - const auto& child = childpair.second; - + for (const auto& [name, child] : options) { if (child.isValue()) { try { auto nctype = bout::utils::visit(NcTypeVisitor(), child.value); diff --git a/src/sys/petsclib.cxx b/src/sys/petsclib.cxx index f1cf1a9d1b..bae53a8c7a 100644 --- a/src/sys/petsclib.cxx +++ b/src/sys/petsclib.cxx @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -119,6 +120,12 @@ void PetscLib::setOptionsFromInputFile(SNES& snes) { BOUT_DO_PETSC(SNESSetFromOptions(snes)); } +void PetscLib::setOptionsFromInputFile(TS& ts) { + BOUT_DO_PETSC(TSSetOptionsPrefix(ts, options_prefix.c_str())); + + BOUT_DO_PETSC(TSSetFromOptions(ts)); +} + void PetscLib::cleanup() { BOUT_OMP_SAFE(critical(PetscLib)) { diff --git a/tests/MMS/GBS/makefile b/tests/MMS/GBS/makefile deleted file mode 100644 index 7dbf15255f..0000000000 --- a/tests/MMS/GBS/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = gbs.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/advection/makefile b/tests/MMS/advection/makefile deleted file mode 100644 index 305cd9bebe..0000000000 --- a/tests/MMS/advection/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../../ - -SOURCEC = advection.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/diffusion/makefile b/tests/MMS/diffusion/makefile deleted file mode 100644 index 4b4c30ff62..0000000000 --- a/tests/MMS/diffusion/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../ - -SOURCEC = diffusion.cxx -SOURCEH = mathematica.h -TARGET = cyto - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/diffusion2/makefile b/tests/MMS/diffusion2/makefile deleted file mode 100644 index 4b4c30ff62..0000000000 --- a/tests/MMS/diffusion2/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../ - -SOURCEC = diffusion.cxx -SOURCEH = mathematica.h -TARGET = cyto - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/elm-pb/makefile b/tests/MMS/elm-pb/makefile deleted file mode 100644 index 815a018b94..0000000000 --- a/tests/MMS/elm-pb/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = elm_pb.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/elm-pb/makegrids.py b/tests/MMS/elm-pb/makegrids.py deleted file mode 100644 index b627977469..0000000000 --- a/tests/MMS/elm-pb/makegrids.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python3 -# -# Creates the grid files and input options for -# a set of simulations. These can then be submitted -# to a batch queue and then processed with runtest -# (setting "running = False") -# - -from __future__ import print_function -from __future__ import division - -nxlist = [4, 8, 16, 32, 64, 128] - -from boututils.datafile import DataFile -from boututils.run_wrapper import shell - -from os.path import isfile - -from boutdata.mms import SimpleTokamak, x, y -from sympy import sin, cos - -from math import pi - -shape = SimpleTokamak() - -## Add equilibrium profiles -MU0 = 4.0e-7 * pi - -J0 = 1 - x - sin(x * pi) ** 2 * cos(y) # Parallel current -P0 = 2 + cos(x * pi) # Pressure pedestal -bxcvz = -((1.0 / shape.Rxy) ** 2) * cos(y) # Curvature - -# Normalisation -Lbar = 1.0 -Bbar = 1.0 -J0 = -J0 * shape.Bxy / (MU0 * Lbar) # Turn into A/m^2 -P0 = P0 * Bbar**2 / (2.0 * MU0) # Pascals - -shape.add(P0, "pressure") -shape.add(J0, "Jpar0") -shape.add(bxcvz, "bxcvz") - -for nx in nxlist: - # Generate a new mesh file - - filename = "grid%d.nc" % nx - - if isfile(filename): - print("Grid file '%s' already exists" % filename) - else: - print("Creating grid file '%s'" % filename) - f = DataFile(filename, create=True) - shape.write(nx, nx, f) - f.close() - - # Generate BOUT.inp file - - directory = "grid%d" % nx - shell("mkdir " + directory) - shell("cp data/BOUT.inp " + directory) - shell("sed -i 's/MZ = 17/MZ = %d/g' %s/BOUT.inp" % (nx, directory)) - shell( - 'sed -i \'s/grid = "grid16.nc"/grid = "%s"/g\' %s/BOUT.inp' - % (filename, directory) - ) diff --git a/tests/MMS/fieldalign/doc/makefile b/tests/MMS/fieldalign/doc/makefile deleted file mode 100644 index 70bb3220d0..0000000000 --- a/tests/MMS/fieldalign/doc/makefile +++ /dev/null @@ -1,12 +0,0 @@ - -DOCS = fieldalign.pdf - -.PHONY: all - -all: $(DOCS) - -%.pdf: %.tex - latexmk -pdf $< -interaction=batchmode - -clean: - latexmk -C diff --git a/tests/MMS/fieldalign/makefile b/tests/MMS/fieldalign/makefile deleted file mode 100644 index 30f47ccf0a..0000000000 --- a/tests/MMS/fieldalign/makefile +++ /dev/null @@ -1,7 +0,0 @@ - -BOUT_TOP = ../../../ - -SOURCEC = fieldalign.cxx -SOURCEH = mathematica.h - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/hw/makefile b/tests/MMS/hw/makefile deleted file mode 100644 index 0a68a26d50..0000000000 --- a/tests/MMS/hw/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = hw.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/laplace/data/BOUT.inp b/tests/MMS/laplace/data/BOUT.inp index 1965b1e8f7..5b3cc37b09 100644 --- a/tests/MMS/laplace/data/BOUT.inp +++ b/tests/MMS/laplace/data/BOUT.inp @@ -5,7 +5,7 @@ MXG = 1 solution = sin(pi*x) -input = -pi^2*sin(pi*x) +input_field = -pi^2*sin(pi*x) [mesh] diff --git a/tests/MMS/laplace/laplace.cxx b/tests/MMS/laplace/laplace.cxx index 54dbaaba67..fbcdee355c 100644 --- a/tests/MMS/laplace/laplace.cxx +++ b/tests/MMS/laplace/laplace.cxx @@ -1,16 +1,21 @@ #include - #include +#include #include #include +#include + +#include using bout::globals::mesh; +using namespace std::string_literals; int main(int argc, char** argv) { int init_err = BoutInitialise(argc, argv); if (init_err < 0) { return 0; - } else if (init_err > 0) { + } + if (init_err > 0) { return init_err; } @@ -31,16 +36,14 @@ int main(int argc, char** argv) { FieldFactory fact(mesh); - std::shared_ptr gen = fact.parse("input"); - output << "GEN = " << gen->str() << endl; - - Field3D input = fact.create3D("input"); - - Field3D result = lap->solve(input); - - Field3D solution = fact.create3D("solution"); + const auto input_name = "input_field"s; + const auto gen = fact.parse(input_name); + output.write("GEN = {}\n", gen->str()); - Field3D error = result - solution; + const Field3D input = fact.create3D(input_name); + const Field3D result = lap->solve(input); + const Field3D solution = fact.create3D("solution"); + const Field3D error = result - solution; Options dump; dump["input"] = input; diff --git a/tests/MMS/laplace/makefile b/tests/MMS/laplace/makefile deleted file mode 100644 index fa561d91da..0000000000 --- a/tests/MMS/laplace/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = laplace.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/makefile b/tests/MMS/makefile deleted file mode 120000 index 065bc377f3..0000000000 --- a/tests/MMS/makefile +++ /dev/null @@ -1 +0,0 @@ -../integrated/makefile \ No newline at end of file diff --git a/tests/MMS/spatial/advection/makefile b/tests/MMS/spatial/advection/makefile deleted file mode 100644 index fdb2043641..0000000000 --- a/tests/MMS/spatial/advection/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = advection.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/spatial/d2dx2/data/BOUT.inp b/tests/MMS/spatial/d2dx2/data/BOUT.inp index 5c1deaf0af..cdc0d96139 100644 --- a/tests/MMS/spatial/d2dx2/data/BOUT.inp +++ b/tests/MMS/spatial/d2dx2/data/BOUT.inp @@ -5,7 +5,7 @@ MXG = 1 MYG = 1 # No guard cells in Y -input = sin(0.5*pi*x) +input_field = sin(0.5*pi*x) solution = -sin(0.5*pi*x) * 0.25*pi*pi [mesh] diff --git a/tests/MMS/spatial/d2dx2/makefile b/tests/MMS/spatial/d2dx2/makefile deleted file mode 100644 index 8975c2c713..0000000000 --- a/tests/MMS/spatial/d2dx2/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../../../ - -SOURCEC = test_d2dx2.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/spatial/d2dx2/test_d2dx2.cxx b/tests/MMS/spatial/d2dx2/test_d2dx2.cxx index 6b35b719e1..7f7127cea9 100644 --- a/tests/MMS/spatial/d2dx2/test_d2dx2.cxx +++ b/tests/MMS/spatial/d2dx2/test_d2dx2.cxx @@ -4,7 +4,9 @@ #include #include +#include #include +#include using bout::globals::mesh; @@ -12,8 +14,9 @@ int main(int argc, char** argv) { BoutInitialise(argc, argv); - Field3D input = FieldFactory::get()->create3D("input", Options::getRoot(), mesh); - Field3D solution = FieldFactory::get()->create3D("solution", Options::getRoot(), mesh); + Field3D input = FieldFactory::get()->create3D("input_field", Options::getRoot(), mesh); + const Field3D solution = + FieldFactory::get()->create3D("solution", Options::getRoot(), mesh); // At this point the boundary cells are set to the analytic solution input.setBoundary("bndry"); @@ -21,7 +24,7 @@ int main(int argc, char** argv) { // Boundaries of input now set using extrapolation around mid-point boundary - Field3D result = D2DX2(input); + const Field3D result = D2DX2(input); // At this point result is not set in the boundary cells Options dump; diff --git a/tests/MMS/spatial/d2dz2/data/BOUT.inp b/tests/MMS/spatial/d2dz2/data/BOUT.inp index 6618d6f574..640411c112 100644 --- a/tests/MMS/spatial/d2dz2/data/BOUT.inp +++ b/tests/MMS/spatial/d2dz2/data/BOUT.inp @@ -5,7 +5,7 @@ zperiod = 1 MXG = 0 # No guard cells in X MYG = 1 # No guard cells in Y -input = sin(z) +input_field = sin(z) solution = -sin(z) [mesh] diff --git a/tests/MMS/spatial/d2dz2/makefile b/tests/MMS/spatial/d2dz2/makefile deleted file mode 100644 index 043b0567dd..0000000000 --- a/tests/MMS/spatial/d2dz2/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../../../ - -SOURCEC = test_d2dz2.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/spatial/d2dz2/test_d2dz2.cxx b/tests/MMS/spatial/d2dz2/test_d2dz2.cxx index 0b7aa2cde4..68a12b062f 100644 --- a/tests/MMS/spatial/d2dz2/test_d2dz2.cxx +++ b/tests/MMS/spatial/d2dz2/test_d2dz2.cxx @@ -4,7 +4,9 @@ #include #include +#include #include +#include using bout::globals::mesh; @@ -12,8 +14,10 @@ int main(int argc, char** argv) { BoutInitialise(argc, argv); - Field3D input = FieldFactory::get()->create3D("input", Options::getRoot(), mesh); - Field3D solution = FieldFactory::get()->create3D("solution", Options::getRoot(), mesh); + const Field3D input = + FieldFactory::get()->create3D("input_field", Options::getRoot(), mesh); + const Field3D solution = + FieldFactory::get()->create3D("solution", Options::getRoot(), mesh); Field3D result = D2DZ2(input); diff --git a/tests/MMS/spatial/diffusion/makefile b/tests/MMS/spatial/diffusion/makefile deleted file mode 100644 index 47a79d0916..0000000000 --- a/tests/MMS/spatial/diffusion/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = diffusion.cxx -SOURCEH = mathematica.h -TARGET = diffusion - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/spatial/fci/CMakeLists.txt b/tests/MMS/spatial/fci/CMakeLists.txt index 94b9682c9c..b01c765fa6 100644 --- a/tests/MMS/spatial/fci/CMakeLists.txt +++ b/tests/MMS/spatial/fci/CMakeLists.txt @@ -3,5 +3,6 @@ bout_add_mms_test(MMS-spatial-fci USE_RUNTEST USE_DATA_BOUT_INP REQUIRES zoidberg_FOUND + REQUIRES BOUT_USE_METRIC_3D PROCESSORS 2 ) diff --git a/tests/MMS/spatial/fci/data/BOUT.inp b/tests/MMS/spatial/fci/data/BOUT.inp index 20ec3b69b0..93e2101473 100644 --- a/tests/MMS/spatial/fci/data/BOUT.inp +++ b/tests/MMS/spatial/fci/data/BOUT.inp @@ -1,16 +1,17 @@ - -# generated by ../mms.py 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 +grad_par_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) +grad2_par2_solution = (6.28318530717959*(0.01*x + 0.045)*(6.28318530717959*(0.01*x + 0.045)*(-4*sin(y - 2*z) - sin(y - z)) + 1.25663706143592*sin(y - 2*z) + 0.628318530717959*sin(y - z))/sqrt((0.01*x + 0.045)^2 + 1.0) + 0.628318530717959*(6.28318530717959*(0.01*x + 0.045)*(2*sin(y - 2*z) + sin(y - z)) - 0.628318530717959*sin(y - 2*z) - 0.628318530717959*sin(y - z))/sqrt((0.01*x + 0.045)^2 + 1.0))/sqrt((0.01*x + 0.045)^2 + 1.0) +div_par_solution = (0.01*x + 0.045)*(-12.5663706143592*cos(y - 2*z) - 6.28318530717959*cos(y - z) + 0.628318530717959*(cos(y - 2*z) + cos(y - z))/(0.01*x + 0.045))/sqrt((0.01*x + 0.045)^2 + 1.0) +div_par_K_grad_par_solution = (0.01*x + 0.045)*(6.28318530717959*sin(y - z) - 0.628318530717959*sin(y - z)/(0.01*x + 0.045))*(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))/((0.01*x + 0.045)^2 + 1.0) + (6.28318530717959*(0.01*x + 0.045)*(6.28318530717959*(0.01*x + 0.045)*(-4*sin(y - 2*z) - sin(y - z)) + 1.25663706143592*sin(y - 2*z) + 0.628318530717959*sin(y - z))/sqrt((0.01*x + 0.045)^2 + 1.0) + 0.628318530717959*(6.28318530717959*(0.01*x + 0.045)*(2*sin(y - 2*z) + sin(y - z)) - 0.628318530717959*sin(y - 2*z) - 0.628318530717959*sin(y - z))/sqrt((0.01*x + 0.045)^2 + 1.0))*cos(y - z)/sqrt((0.01*x + 0.045)^2 + 1.0) +K = cos(y - z) +laplace_par_solution = (0.01*x + 0.045)*(6.28318530717959*(6.28318530717959*(0.01*x + 0.045)*(-4*sin(y - 2*z) - sin(y - z)) + 1.25663706143592*sin(y - 2*z) + 0.628318530717959*sin(y - z))/sqrt((0.01*x + 0.045)^2 + 1.0) + 0.628318530717959*(6.28318530717959*(0.01*x + 0.045)*(2*sin(y - 2*z) + sin(y - z)) - 0.628318530717959*sin(y - 2*z) - 0.628318530717959*sin(y - z))/((0.01*x + 0.045)*sqrt((0.01*x + 0.045)^2 + 1.0)))/sqrt((0.01*x + 0.045)^2 + 1.0) [mesh] symmetricglobalx = true file = fci.grid.nc +MXG = 1 +MYG = 1 +NXPE = 1 [mesh:ddy] first = C2 diff --git a/tests/MMS/spatial/fci/fci_mms.cxx b/tests/MMS/spatial/fci/fci_mms.cxx index 18405a7f88..265f14ea6e 100644 --- a/tests/MMS/spatial/fci/fci_mms.cxx +++ b/tests/MMS/spatial/fci/fci_mms.cxx @@ -1,6 +1,34 @@ #include "bout/bout.hxx" -#include "bout/derivs.hxx" +#include "bout/build_config.hxx" +#include "bout/difops.hxx" +#include "bout/field3d.hxx" #include "bout/field_factory.hxx" +#include "bout/options.hxx" + +#include + +namespace { +auto fci_op_test(const std::string& name, Options& dump, const Field3D& input, + const Field3D& result) { + auto* mesh = input.getMesh(); + Field3D solution{FieldFactory::get()->create3D(fmt::format("{}_solution", name), + Options::getRoot(), mesh)}; + Field3D error{result - solution}; + + dump[fmt::format("{}_l_2", name)] = sqrt(mean(SQ(error), true, "RGN_NOBNDRY")); + dump[fmt::format("{}_l_inf", name)] = max(abs(error), true, "RGN_NOBNDRY"); + + dump[fmt::format("{}_result", name)] = result; + dump[fmt::format("{}_error", name)] = error; + dump[fmt::format("{}_input", name)] = input; + dump[fmt::format("{}_solution", name)] = solution; + + for (int slice = 1; slice < mesh->ystart; ++slice) { + dump[fmt::format("{}_input.ynext(-{})", name, slice)] = input.ynext(-slice); + dump[fmt::format("{}_input.ynext({})", name, slice)] = input.ynext(slice); + } +} +} // namespace int main(int argc, char** argv) { BoutInitialise(argc, argv); @@ -8,30 +36,20 @@ int main(int argc, char** argv) { using bout::globals::mesh; Field3D input{FieldFactory::get()->create3D("input_field", Options::getRoot(), mesh)}; - Field3D solution{FieldFactory::get()->create3D("solution", Options::getRoot(), mesh)}; - - // Communicate to calculate parallel transform - mesh->communicate(input); + Field3D K{FieldFactory::get()->create3D("K", Options::getRoot(), mesh)}; - Field3D result{Grad_par(input)}; - Field3D error{result - solution}; + // Communicate to calculate parallel transform. + mesh->communicate(input, K); 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"); - - dump["result"] = result; - dump["error"] = error; - dump["input"] = input; - dump["solution"] = solution; - - for (int slice = 1; slice < mesh->ystart; ++slice) { - dump[fmt::format("input.ynext(-{})", slice)] = input.ynext(-slice); - dump[fmt::format("input.ynext({})", slice)] = input.ynext(slice); - } + fci_op_test("grad_par", dump, input, Grad_par(input)); + fci_op_test("grad2_par2", dump, input, Grad2_par2(input)); + fci_op_test("div_par", dump, input, Div_par(input)); + fci_op_test("div_par_K_grad_par", dump, input, Div_par_K_Grad_par(K, input)); + fci_op_test("laplace_par", dump, input, Laplace_par(input)); bout::writeDefaultOutputFile(dump); diff --git a/tests/MMS/spatial/fci/makefile b/tests/MMS/spatial/fci/makefile deleted file mode 100644 index 88ba6c77e7..0000000000 --- a/tests/MMS/spatial/fci/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../../.. - -SOURCEC = fci_mms.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/spatial/fci/mms.py b/tests/MMS/spatial/fci/mms.py index 994b3f9761..b28e337ac0 100755 --- a/tests/MMS/spatial/fci/mms.py +++ b/tests/MMS/spatial/fci/mms.py @@ -3,13 +3,18 @@ # Generate manufactured solution and sources for FCI test # -from boutdata.mms import * +from math import pi +import warnings -from sympy import sin, cos, sqrt +from boututils.boutwarnings import AlwaysWarning +from boutdata.data import BoutOptionsFile +from boutdata.mms import diff, exprToStr, x, y, z +from sympy import sin, cos, sqrt, Expr -from math import pi +warnings.simplefilter("ignore", AlwaysWarning) f = sin(y - z) + sin(y - 2 * z) +K = cos(z - y) Lx = 0.1 Ly = 10.0 @@ -23,12 +28,42 @@ B = sqrt(Bpx**2 + Bt**2) -def FCI_ddy(f): +def FCI_grad_par(f: Expr) -> Expr: return (Bt * diff(f, y) * 2.0 * pi / Ly + Bpx * diff(f, z) * 2.0 * pi / Lz) / B +def FCI_grad2_par2(f: Expr) -> Expr: + return FCI_grad_par(FCI_grad_par(f)) + + +def FCI_div_par(f: Expr) -> Expr: + return Bpx * FCI_grad_par(f / Bpx) + + +def FCI_div_par_K_grad_par(f: Expr, K: Expr) -> Expr: + return (K * FCI_grad2_par2(f)) + (FCI_div_par(K) * FCI_grad_par(f)) + + +def FCI_Laplace_par(f: Expr) -> Expr: + return FCI_div_par(FCI_grad_par(f)) + + ############################################ # Equations solved -print("input_field = " + exprToStr(f)) -print("solution = " + exprToStr(FCI_ddy(f))) +options = BoutOptionsFile("data/BOUT.inp") + +for name, expr in ( + ("input_field", f), + ("K", K), + ("grad_par_solution", FCI_grad_par(f)), + ("grad2_par2_solution", FCI_grad2_par2(f)), + ("div_par_solution", FCI_div_par(f)), + ("div_par_K_grad_par_solution", FCI_div_par_K_grad_par(f, K)), + ("laplace_par_solution", FCI_Laplace_par(f)), +): + expr_str = exprToStr(expr) + print(f"{name} = {expr_str}") + options[name] = expr_str + +options.write("data/BOUT.inp", overwrite=True) diff --git a/tests/MMS/spatial/fci/runtest b/tests/MMS/spatial/fci/runtest index c8bb3f914b..4d5022d4b4 100755 --- a/tests/MMS/spatial/fci/runtest +++ b/tests/MMS/spatial/fci/runtest @@ -6,226 +6,249 @@ # Cores: 2 # requires: zoidberg -from boututils.run_wrapper import build_and_log, launch_safe -from boutdata.collect import collect -import boutconfig as conf - -from numpy import array, log, polyfit, linspace, arange - -import pickle - -from sys import stdout +import argparse +import json +import pathlib +import sys +from time import time +import boutconfig as conf import zoidberg as zb - -nx = 4 # Not changed for these tests - +from boutdata.collect import collect +from boututils.run_wrapper import build_and_log, launch_safe +from numpy import arange, array, linspace, log, polyfit + +# Global parameters +DIRECTORY = "data" +NPROC = 2 +MTHREAD = 2 +OPERATORS = ("grad_par", "grad2_par2", "div_par", "div_par_K_grad_par", "laplace_par") +# Note that we need at least _2_ interior points for hermite spline +# interpolation due to an awkwardness with the boundaries +NX = 4 # Resolution in y and z -nlist = [8, 16, 32, 64, 128] - -# Number of parallel slices (in each direction) -nslices = [1] - -directory = "data" - -nproc = 2 -mthread = 2 - - -success = True - -error_2 = {} -error_inf = {} -method_orders = {} - -# Run with periodic Y? -yperiodic = True - -failures = [] - -build_and_log("FCI MMS test") - -for nslice in nslices: - for method in [ - "hermitespline", - "lagrange4pt", - "bilinear", - "monotonichermitespline", - "monotonichermitesplinelegacy", - ]: - error_2[nslice] = [] - error_inf[nslice] = [] - - # Which central difference scheme to use and its expected order - order = nslice * 2 - method_orders[nslice] = {"name": "C{}".format(order), "order": order} - - for n in nlist: - # Define the magnetic field using new poloidal gridding method - # Note that the Bz and Bzprime parameters here must be the same as in mms.py - field = zb.field.Slab(Bz=0.05, Bzprime=0.1) - # Create rectangular poloidal grids - poloidal_grid = zb.poloidal_grid.RectangularPoloidalGrid( - nx, n, 0.1, 1.0, MXG=1 - ) - # Set the ylength and y locations - ylength = 10.0 - - if yperiodic: - ycoords = linspace(0.0, ylength, n, endpoint=False) - else: - # Doesn't include the end points - ycoords = (arange(n) + 0.5) * ylength / float(n) - - # Create the grid - grid = zb.grid.Grid(poloidal_grid, ycoords, ylength, yperiodic=yperiodic) - # Make and write maps - from scipy.interpolate import RectBivariateSpline as RBS - - def myRBS(a, b, c): - mx, my = c.shape - kx = max(mx - 1, 1) - kx = min(kx, 3) - return RBS(a, b, c, kx=kx) - - zb.poloidal_grid.RectBivariateSpline = myRBS - - maps = zb.make_maps(grid, field, nslice=nslice, quiet=True, MXG=1) - zb.write_maps( - grid, - field, - maps, - new_names=False, - metric2d=conf.isMetric2D(), - quiet=True, - ) - - args = " MZ={} MYG={} mesh:paralleltransform:y_periodic={} mesh:ddy:first={} NXPE={}".format( - n, - nslice, - yperiodic, - method_orders[nslice]["name"], - ( - 1 - if "legacy" in method - else 2 if conf.has["petsc"] and "hermitespline" in method else 1 - ), - ) - args += f" mesh:paralleltransform:xzinterpolation:type={method}" - - # Command to run - cmd = "./fci_mms " + args - - print("Running command: " + cmd) - - # Launch using MPI - s, out = launch_safe(cmd, nproc=nproc, mthread=mthread, pipe=True) - - # Save output to log file - with open("run.log." + str(n), "w") as f: - f.write(out) - - if s: - print("Run failed!\nOutput was:\n") - print(out) - exit(s) - - # Collect data - l_2 = collect( - "l_2", - tind=[1, 1], - info=False, - path=directory, - xguards=False, - yguards=False, - ) - l_inf = collect( - "l_inf", - tind=[1, 1], - info=False, - path=directory, - xguards=False, - yguards=False, - ) - - error_2[nslice].append(l_2) - error_inf[nslice].append(l_inf) - - print("Errors : l-2 {:f} l-inf {:f}".format(l_2, l_inf)) - - dx = 1.0 / array(nlist) - - # Calculate convergence order - fit = polyfit(log(dx), log(error_2[nslice]), 1) - order = fit[0] - stdout.write("Convergence order = {:f} (fit)".format(order)) - - order = log(error_2[nslice][-2] / error_2[nslice][-1]) / log(dx[-2] / dx[-1]) - stdout.write(", {:f} (small spacing)".format(order)) - - # Should be close to the expected order - if order > method_orders[nslice]["order"] * ( - 0.6 if "monot" in method else 0.95 - ): - print("............ PASS\n") - else: - print("............ FAIL\n") - success = False - failures.append(method_orders[nslice]["name"]) - - -with open("fci_mms.pkl", "wb") as output: - pickle.dump(nlist, output) - for nslice in nslices: - pickle.dump(error_2[nslice], output) - pickle.dump(error_inf[nslice], output) - -# Do we want to show the plot as well as save it to file. -showPlot = True - -if False: +NLIST = [8, 16, 32, 64] +dx = 1.0 / array(NLIST) + + +def quiet_collect(name: str) -> float: + # Index to return a plain (numpy) float rather than `BoutArray` + return collect( + name, + tind=[1, 1], + info=False, + path=DIRECTORY, + xguards=False, + yguards=False, + )[()] + + +def assert_convergence(error, dx, name, order) -> bool: + fit = polyfit(log(dx), log(error), 1) + order = fit[0] + print(f"{name} convergence order = {order:f} (fit)", end="") + + order = log(error[-2] / error[-1]) / log(dx[-2] / dx[-1]) + print(f", {order:f} (small spacing)", end="") + + # Should be close to the expected order + success = order > order * 0.95 + print(f"\t............ {'PASS' if success else 'FAIL'}") + + return success + + +def run_fci_operators( + nslice: int, nz: int, yperiodic: bool, name: str +) -> dict[str, float]: + # Define the magnetic field using new poloidal gridding method + # Note that the Bz and Bzprime parameters here must be the same as in mms.py + field = zb.field.Slab(Bz=0.05, Bzprime=0.1) + # Create rectangular poloidal grids + poloidal_grid = zb.poloidal_grid.RectangularPoloidalGrid(NX, nz, 0.1, 1.0, MXG=1) + # Set the ylength and y locations + ylength = 10.0 + + if yperiodic: + ycoords = linspace(0.0, ylength, nz, endpoint=False) + else: + # Doesn't include the end points + ycoords = (arange(nz) + 0.5) * ylength / float(nz) + + # Create the grid + grid = zb.grid.Grid(poloidal_grid, ycoords, ylength, yperiodic=yperiodic) + maps = zb.make_maps(grid, field, nslice=nslice, quiet=True, MXG=1) + zb.write_maps( + grid, + field, + maps, + new_names=False, + metric2d=conf.isMetric2D(), + quiet=True, + ) + + # Command to run + args = f"MZ={nz} MYG={nslice} mesh:paralleltransform:y_periodic={yperiodic} {name}" + cmd = f"./fci_mms {args}" + print(f"Running command: {cmd}", end="") + + # Launch using MPI + start = time() + status, out = launch_safe(cmd, nproc=NPROC, mthread=MTHREAD, pipe=True) + print(f" ... done in {time() - start:.3}s") + + # Save output to log file + pathlib.Path(f"run.log.{nz}").write_text(out) + + if status: + print(f"Run failed!\nOutput was:\n{out}") + sys.exit(status) + + return { + operator: { + "l_2": quiet_collect(f"{operator}_l_2"), + "l_inf": quiet_collect(f"{operator}_l_inf"), + } + for operator in OPERATORS + } + + +def transpose( + errors: list[dict[str, dict[str, float]]], +) -> dict[str, dict[str, list[float]]]: + """Turn a list of {operator: error} into a dict of {operator: [errors]}""" + + kinds = ("l_2", "l_inf") + result = {operator: {kind: [] for kind in kinds} for operator in OPERATORS} + for error in errors: + for k, v in error.items(): + for kind in kinds: + result[k][kind].append(v[kind]) + return result + + +def check_fci_operators(name: str, case: dict) -> bool: + failures = [] + + nslice = case["nslice"] + yperiodic = case["yperiodic"] + order = case["order"] + args = case["args"] + + all_errors = [] + + for n in NLIST: + errors = run_fci_operators(nslice, n, yperiodic, args) + all_errors.append(errors) + + for operator in OPERATORS: + l_2 = errors[operator]["l_2"] + l_inf = errors[operator]["l_inf"] + + print(f"{operator} errors: l-2 {l_2:f} l-inf {l_inf:f}") + + final_errors = transpose(all_errors) + for operator in OPERATORS: + test_name = f"{operator} {name}" + success = assert_convergence( + final_errors[operator]["l_2"], dx, test_name, order + ) + if not success: + failures.append(test_name) + + return final_errors, failures + + +def make_plots(cases: dict[str, dict]): try: - # Plot using matplotlib if available import matplotlib.pyplot as plt + except ImportError: + print("No matplotlib") + return - fig, ax = plt.subplots(1, 1) - - for nslice in nslices: - ax.plot( - dx, - error_2[nslice], - "-", - label="{} $l_2$".format(method_orders[nslice]["name"]), - ) - ax.plot( - dx, - error_inf[nslice], - "--", - label="{} $l_\\inf$".format(method_orders[nslice]["name"]), - ) + num_operators = len(OPERATORS) + fig, axes = plt.subplots(1, num_operators, figsize=(num_operators * 4, 4)) + + for ax, operator in zip(axes, OPERATORS): + for name, case in cases.items(): + ax.loglog(dx, case[operator]["l_2"], "-", label=f"{name} $l_2$") + ax.loglog(dx, case[operator]["l_inf"], "--", label=f"{name} $l_\\inf$") ax.legend(loc="upper left") ax.grid() - ax.set_yscale("log") - ax.set_xscale("log") - ax.set_title("error scaling") + ax.set_title(f"Error scaling for {operator}") ax.set_xlabel(r"Mesh spacing $\delta x$") ax.set_ylabel("Error norm") - plt.savefig("fci_mms.pdf") - - print("Plot saved to fci_mms.pdf") - - if showPlot: - plt.show() - plt.close() - except ImportError: - print("No matplotlib") - -if success: - print("All tests passed") - exit(0) -else: - print("Some tests failed:") - for failure in failures: - print("\t" + failure) - exit(1) + fig.tight_layout() + fig.savefig("fci_mms.pdf") + print("Plot saved to fci_mms.pdf") + + if args.show_plots: + plt.show() + plt.close() + + +if __name__ == "__main__": + build_and_log("FCI MMS test") + + parser = argparse.ArgumentParser("Error scaling test for FCI operators") + parser.add_argument( + "--make-plots", action="store_true", help="Create plots of error scaling" + ) + parser.add_argument( + "--show-plots", + action="store_true", + help="Stop and show plots, implies --make-plots", + ) + parser.add_argument( + "--dump-errors", + type=str, + help="Output file to dump errors as JSON", + default="fci_operator_errors.json", + ) + + args = parser.parse_args() + + success = True + failures = [] + cases = { + "nslice=1 hermitespline": { + "nslice": 1, + "order": 2, + "yperiodic": True, + "args": "mesh:ddy:first=C2 mesh:paralleltransform:xzinterpolation:type=hermitespline", + }, + "nslice=1 lagrange4pt": { + "nslice": 1, + "order": 2, + "yperiodic": True, + "args": "mesh:ddy:first=C2 mesh:paralleltransform:xzinterpolation:type=lagrange4pt", + }, + "nslice=1 monotonichermitespline": { + "nslice": 1, + "order": 2, + "yperiodic": True, + "args": "mesh:ddy:first=C2 mesh:paralleltransform:xzinterpolation:type=monotonichermitespline", + }, + } + + for name, case in cases.items(): + error2, failures_ = check_fci_operators(name, case) + case.update(error2) + failures.extend(failures_) + success &= len(failures) == 0 + + if args.dump_errors: + pathlib.Path(args.dump_errors).write_text(json.dumps(cases)) + + if args.make_plots or args.show_plots: + make_plots(cases) + + if success: + print("\nAll tests passed") + else: + print("\nSome tests failed:") + for failure in failures: + print(f"\t{failure}") + + sys.exit(0 if success else 1) diff --git a/tests/MMS/test_suite_make b/tests/MMS/test_suite_make deleted file mode 120000 index 97f7df4edb..0000000000 --- a/tests/MMS/test_suite_make +++ /dev/null @@ -1 +0,0 @@ -../integrated/test_suite_make \ No newline at end of file diff --git a/tests/MMS/time/makefile b/tests/MMS/time/makefile deleted file mode 100644 index a45b4a3888..0000000000 --- a/tests/MMS/time/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../../ - -SOURCEC = time.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/tokamak/makefile b/tests/MMS/tokamak/makefile deleted file mode 100644 index f94969cccf..0000000000 --- a/tests/MMS/tokamak/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../../ - -SOURCEC = tokamak.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/wave-1d-y/makefile b/tests/MMS/wave-1d-y/makefile deleted file mode 100644 index fb4dd1430a..0000000000 --- a/tests/MMS/wave-1d-y/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../ - -SOURCEC = wave.cxx -SOURCEH = mathematica.h -TARGET = wave - -include $(BOUT_TOP)/make.config diff --git a/tests/MMS/wave-1d/makefile b/tests/MMS/wave-1d/makefile deleted file mode 100644 index fb4dd1430a..0000000000 --- a/tests/MMS/wave-1d/makefile +++ /dev/null @@ -1,8 +0,0 @@ - -BOUT_TOP = ../../../ - -SOURCEC = wave.cxx -SOURCEH = mathematica.h -TARGET = wave - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/makefile b/tests/integrated/makefile deleted file mode 100644 index 29215a7185..0000000000 --- a/tests/integrated/makefile +++ /dev/null @@ -1,33 +0,0 @@ -# Makefile for example codes -# Works in the same way as the root Makefile - -BOUT_TOP = ../.. - -BUILD = $(shell PYTHONPATH=../../tools/pylib:$$PYTHONPATH ./test_suite_make --get-list) -BUILD_ALL = $(shell PYTHONPATH=../../tools/pylib:$$PYTHONPATH ./test_suite_make --get-list --all) - -CHECKING = $(shell PYTHONPATH=../../tools/pylib:$$PYTHONPATH ./test_suite --get-list) -CHECKING_ALL = $(shell PYTHONPATH=../../tools/pylib:$$PYTHONPATH ./test_suite --get-list --all) - -include $(BOUT_TOP)/make.config - -CHECKING_ = $(CHECKING:%=%_checking) -CHECKING_ALL_ = $(CHECKING_ALL:%=%_checking) - -DIRS_CLEAN = $(BUILD) - -.PHONY: $(BUILD_ALL) $(CHECKING_ALL) check - -all: $(BUILD) - -all-all: $(BUILD_ALL) - -buildncheck: all check - -$(BUILDALL): - @$(MAKE) --no-print-directory -C $@ - -check: $(CHECKING_) - -$(CHECKING_ALL_): - @$(MAKE) --no-print-directory -C $(@:%_checking=%) runtest diff --git a/tests/integrated/test-backtrace/CMakeLists.txt b/tests/integrated/test-backtrace/CMakeLists.txt index aa66eeed56..b20262f1b1 100644 --- a/tests/integrated/test-backtrace/CMakeLists.txt +++ b/tests/integrated/test-backtrace/CMakeLists.txt @@ -1,5 +1,6 @@ bout_add_integrated_test(test-backtrace SOURCES boutexcept.cxx REQUIRES BOUT_USE_BACKTRACE + CONFLICTS CMAKE_SYSTEM_NAME MATCHES "FreeBSD" USE_RUNTEST ) diff --git a/tests/integrated/test-backtrace/makefile b/tests/integrated/test-backtrace/makefile deleted file mode 100644 index 27a1ecaf3a..0000000000 --- a/tests/integrated/test-backtrace/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP ?= ../../.. - -SOURCEC = boutexcept.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-beuler/makefile b/tests/integrated/test-beuler/makefile deleted file mode 100644 index 4eb9387e29..0000000000 --- a/tests/integrated/test-beuler/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test_beuler.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-bout-override-default-option/makefile b/tests/integrated/test-bout-override-default-option/makefile deleted file mode 100644 index 72fb7693e9..0000000000 --- a/tests/integrated/test-bout-override-default-option/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test-bout-override-default-option.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-bout-override-default-option/runtest b/tests/integrated/test-bout-override-default-option/runtest index 42d75ca100..c13f4439b3 100755 --- a/tests/integrated/test-bout-override-default-option/runtest +++ b/tests/integrated/test-bout-override-default-option/runtest @@ -1,3 +1,3 @@ -#!/bin/bash +#!/usr/bin/env bash make && ./test-bout-override-default-option diff --git a/tests/integrated/test-code-style/runtest b/tests/integrated/test-code-style/runtest index cfd277d71b..d392f9110f 100755 --- a/tests/integrated/test-code-style/runtest +++ b/tests/integrated/test-code-style/runtest @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #requires not make diff --git a/tests/integrated/test-collect/makefile b/tests/integrated/test-collect/makefile deleted file mode 100644 index d599972ccb..0000000000 --- a/tests/integrated/test-collect/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test-collect.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-command-args/makefile b/tests/integrated/test-command-args/makefile deleted file mode 100644 index 395ef9b6fa..0000000000 --- a/tests/integrated/test-command-args/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = command-args.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-command-args/runtest b/tests/integrated/test-command-args/runtest index 6830959343..39939bb105 100755 --- a/tests/integrated/test-command-args/runtest +++ b/tests/integrated/test-command-args/runtest @@ -5,10 +5,14 @@ import os import re import shutil import unittest +import platform + + +OUTPUT_FILE = "stdout.log" if platform.system() == "FreeBSD" else "stderr.log" class TestCommandLineArgs(unittest.TestCase): - command = "./command-args 2>stderr.log" + command = "./command-args >stdout.log 2>stderr.log" def makeDirAndCopyInput(self, path): os.mkdir(path) @@ -16,7 +20,7 @@ class TestCommandLineArgs(unittest.TestCase): def setUp(self): try: - os.remove("stderr.log") + os.remove(OUTPUT_FILE) except OSError: pass shutil.rmtree("./data", ignore_errors=True) @@ -29,7 +33,7 @@ class TestCommandLineArgs(unittest.TestCase): def testNoArgumentsNoDirectory(self): with self.assertRaises(RuntimeError): launch_safe(self.command, pipe=True, nproc=1, mthread=1) - with open("stderr.log") as f: + with open(OUTPUT_FILE) as f: contents = f.read() self.assertIn( '"data" does not exist', @@ -97,7 +101,7 @@ class TestCommandLineArgs(unittest.TestCase): launch_safe( self.command + " -d non_existent", pipe=True, nproc=1, mthread=1 ) - with open("stderr.log") as f: + with open(OUTPUT_FILE) as f: contents = f.read() self.assertIn( '"non_existent" does not exist', @@ -108,7 +112,7 @@ class TestCommandLineArgs(unittest.TestCase): def testDirectoryArgumentNonDirectory(self): with self.assertRaises(RuntimeError): launch_safe(self.command + " -d runtest", pipe=True, nproc=1, mthread=1) - with open("stderr.log") as f: + with open(OUTPUT_FILE) as f: contents = f.read() self.assertIn( '"runtest" is not a directory', @@ -175,21 +179,24 @@ class TestCommandLineArgs(unittest.TestCase): "--foo_flag", "some:option=value", ] - _, out = launch_safe( + launch_safe( self.command + " " + " ".join(extra_options), pipe=True, nproc=1, mthread=1 ) - command_line_options = None - for line in out.splitlines(): - if line.lstrip().startswith("Command line"): - command_line_options = line + with open("stdout.log") as f: + contents = f.read() - for option in extra_options: - self.assertIn( - option, - command_line_options, - msg="FAIL: option {} not printed out".format(option), - ) + command_line_options = None + for line in contents.splitlines(): + if line.lstrip().startswith("Command line"): + command_line_options = line + + for option in extra_options: + self.assertIn( + option, + command_line_options, + msg="FAIL: option {} not printed out".format(option), + ) if __name__ == "__main__": diff --git a/tests/integrated/test-communications/makefile b/tests/integrated/test-communications/makefile deleted file mode 100644 index 62bfa7e1ca..0000000000 --- a/tests/integrated/test-communications/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test-communications.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-compile-examples-petsc/runtest b/tests/integrated/test-compile-examples-petsc/runtest index cd61c30ef5..0f9625af40 100755 --- a/tests/integrated/test-compile-examples-petsc/runtest +++ b/tests/integrated/test-compile-examples-petsc/runtest @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #requires: all_tests #requires: not make diff --git a/tests/integrated/test-compile-examples/runtest b/tests/integrated/test-compile-examples/runtest index 31650adeab..765ea2cbfd 100755 --- a/tests/integrated/test-compile-examples/runtest +++ b/tests/integrated/test-compile-examples/runtest @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #requires: all_tests #requires: not make diff --git a/tests/integrated/test-coordinates-initialization/makefile b/tests/integrated/test-coordinates-initialization/makefile deleted file mode 100644 index 805ac0e1da..0000000000 --- a/tests/integrated/test-coordinates-initialization/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test-coordinates-initialization.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-coordinates-initialization/runtest b/tests/integrated/test-coordinates-initialization/runtest index 53cda495e6..60c3e3c980 100755 --- a/tests/integrated/test-coordinates-initialization/runtest +++ b/tests/integrated/test-coordinates-initialization/runtest @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Cores: 3 diff --git a/tests/integrated/test-cyclic/makefile b/tests/integrated/test-cyclic/makefile deleted file mode 100644 index 9d67f1fce2..0000000000 --- a/tests/integrated/test-cyclic/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_cyclic.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-datafilefacade/makefile b/tests/integrated/test-datafilefacade/makefile deleted file mode 100644 index 26b62c9998..0000000000 --- a/tests/integrated/test-datafilefacade/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-datafile-facade.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-dataformat/makefile b/tests/integrated/test-dataformat/makefile deleted file mode 100644 index ccf812ed6f..0000000000 --- a/tests/integrated/test-dataformat/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_dataformat.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-delp2/makefile b/tests/integrated/test-delp2/makefile deleted file mode 100644 index 0c6ba8b3a9..0000000000 --- a/tests/integrated/test-delp2/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_delp2.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-drift-instability-staggered/makefile b/tests/integrated/test-drift-instability-staggered/makefile deleted file mode 120000 index 4970135770..0000000000 --- a/tests/integrated/test-drift-instability-staggered/makefile +++ /dev/null @@ -1 +0,0 @@ -../test-drift-instability/makefile \ No newline at end of file diff --git a/tests/integrated/test-drift-instability/make_d.pro b/tests/integrated/test-drift-instability/make_d.pro deleted file mode 100644 index 861f846307..0000000000 --- a/tests/integrated/test-drift-instability/make_d.pro +++ /dev/null @@ -1,23 +0,0 @@ -function make_d, path=path - -if not keyword_set(PATH) then path='' - -ni=collect(path=path, var="Ni") -phi=collect(path=path, var="phi") -ni=ni[2,*,*,*] -phi=phi[2,*,*,*] - -du=file_import("uedge.grd_std.cdl") - -new_zmax = collect(path=path, var="ZMAX") ;-fraction of 2PI -rho_s = collect(path=path, var="rho_s") -wci = collect(path=path, var="wci") -t_array = collect(path=path, var="t_array") - -old_zmax=new_zmax/(rho_s/du.hthe0) -print, 'new_zmax=', new_zmax, "; old_zmax=", old_zmax - -d={ni_xyzt:ni, phi_xyzt:phi, rho_s:rho_s, zmax:old_zmax, Zeff:0., AA:0.0, t_array:t_array, wci:wci} - -return,d -end diff --git a/tests/integrated/test-drift-instability/makefile b/tests/integrated/test-drift-instability/makefile deleted file mode 100644 index 419aa3c503..0000000000 --- a/tests/integrated/test-drift-instability/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP ?= ../../.. - -SOURCEC = 2fluid.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-drift-instability/qsubcase.sh b/tests/integrated/test-drift-instability/qsubcase.sh index a7124dc81b..056095b18b 100755 --- a/tests/integrated/test-drift-instability/qsubcase.sh +++ b/tests/integrated/test-drift-instability/qsubcase.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # Create a set of runs and submit to a queueing system e.g. Sun Grid Engine # diff --git a/tests/integrated/test-fci-boundary/get_par_bndry.cxx b/tests/integrated/test-fci-boundary/get_par_bndry.cxx index 6c5c38eaf6..f6154fc61e 100644 --- a/tests/integrated/test-fci-boundary/get_par_bndry.cxx +++ b/tests/integrated/test-fci-boundary/get_par_bndry.cxx @@ -1,5 +1,5 @@ #include "bout/bout.hxx" -#include "bout/derivs.hxx" +#include "bout/field3d.hxx" #include "bout/field_factory.hxx" #include "bout/parallel_boundary_region.hxx" @@ -8,23 +8,24 @@ int main(int argc, char** argv) { using bout::globals::mesh; - std::vector fields; - fields.resize(static_cast(BoundaryParType::SIZE)); + std::vector fields(static_cast(BoundaryParType::SIZE), Field3D{0.0}); + Options dump; for (int i = 0; i < fields.size(); i++) { - fields[i] = Field3D{0.0}; + fields[i].allocate(); + const auto boundary = static_cast(i); + const auto boundary_name = toString(boundary); mesh->communicate(fields[i]); - for (auto& bndry_par : mesh->getBoundariesPar(static_cast(i))) { - output.write("{:s} region\n", toString(static_cast(i))); + for (const auto& bndry_par : mesh->getBoundariesPar(boundary)) { + output.write("{:s} region\n", boundary_name); for (const auto& pnt : *bndry_par) { fields[i][pnt.ind()] += 1; - output.write("{:s} increment\n", toString(static_cast(i))); + output.write("{:s} increment\n", boundary_name); } } - output.write("{:s} done\n", toString(static_cast(i))); + output.write("{:s} done\n", boundary_name); - dump[fmt::format("field_{:s}", toString(static_cast(i)))] = - fields[i]; + dump[fmt::format("field_{:s}", boundary_name)] = fields[i]; } bout::writeDefaultOutputFile(dump); diff --git a/tests/integrated/test-fci-boundary/runtest b/tests/integrated/test-fci-boundary/runtest index 1b1460da53..e749055185 100755 --- a/tests/integrated/test-fci-boundary/runtest +++ b/tests/integrated/test-fci-boundary/runtest @@ -1,29 +1,15 @@ #!/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 +from boutdata.collect import collect import numpy as np -def collect(var): - return _collect( - var, - info=False, - path=directory, - xguards=False, - yguards=False, - ) - - -nprocs = [1] # , 2, 4] +nprocs = [1] mthread = 2 directory = "data" @@ -43,11 +29,6 @@ regions = { } 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": @@ -56,15 +37,18 @@ 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}") + data = collect( + f"field_{k}", + info=False, + path=directory, + xguards=False, + yguards=False, + ) assert np.allclose(data, v), ( - k + " does not match", + f"{k} does not match", np.sum(data), np.sum(v), np.max(data), diff --git a/tests/integrated/test-fci-mpi/fci_mpi.cxx b/tests/integrated/test-fci-mpi/fci_mpi.cxx index 94520dd4a6..cc4fba8ffe 100644 --- a/tests/integrated/test-fci-mpi/fci_mpi.cxx +++ b/tests/integrated/test-fci-mpi/fci_mpi.cxx @@ -1,38 +1,37 @@ +#include "fmt/format.h" #include "bout/bout.hxx" -#include "bout/derivs.hxx" #include "bout/field_factory.hxx" +namespace { +auto fci_mpi_test(int num, Options& dump) { + using bout::globals::mesh; + Field3D input{FieldFactory::get()->create3D(fmt::format("input_{:d}:function", num), + Options::getRoot(), mesh)}; + mesh->communicate(input); + + input.applyParallelBoundary("parallel_neumann_o2"); + + for (int slice = -mesh->ystart; slice <= mesh->ystart; ++slice) { + if (slice == 0) { + continue; + } + Field3D tmp{0.}; + BOUT_FOR(i, tmp.getRegion("RGN_NOBNDRY")) { + tmp[i] = input.ynext(slice)[i.yp(slice)]; + } + dump[fmt::format("output_{:d}_{:+d}", num, slice)] = tmp; + } +} +} // namespace + int main(int argc, char** argv) { BoutInitialise(argc, argv); - { - using bout::globals::mesh; - Options* options = Options::getRoot(); - int i = 0; - const std::string default_str{"not_set"}; - Options dump; - while (true) { - std::string temp_str; - options->get(fmt::format("input_{:d}:function", i), temp_str, default_str); - if (temp_str == default_str) { - break; - } - Field3D input{FieldFactory::get()->create3D(fmt::format("input_{:d}:function", i), - Options::getRoot(), mesh)}; - // options->get(fmt::format("input_{:d}:boundary_perp", i), temp_str, s"free_o3"); - mesh->communicate(input); - input.applyParallelBoundary("parallel_neumann_o2"); - for (int slice = -mesh->ystart; slice <= mesh->ystart; ++slice) { - if (slice != 0) { - Field3D tmp{0.}; - BOUT_FOR(i, tmp.getRegion("RGN_NOBNDRY")) { - tmp[i] = input.ynext(slice)[i.yp(slice)]; - } - dump[fmt::format("output_{:d}_{:+d}", i, slice)] = tmp; - } - } - ++i; - } - bout::writeDefaultOutputFile(dump); + Options dump; + + for (auto num : {0, 1, 2, 3}) { + fci_mpi_test(num, dump); } + + bout::writeDefaultOutputFile(dump); BoutFinalise(); } diff --git a/tests/integrated/test-fci-mpi/runtest b/tests/integrated/test-fci-mpi/runtest index 6676f8f7a5..c18ab0391d 100755 --- a/tests/integrated/test-fci-mpi/runtest +++ b/tests/integrated/test-fci-mpi/runtest @@ -1,57 +1,82 @@ #!/usr/bin/env python3 # # Python script to run and analyse MMS test -# - -# Cores: 8 -# requires: metric_3d -from boututils.run_wrapper import build_and_log, launch_safe, shell_safe +from boututils.run_wrapper import build_and_log, launch_safe from boutdata.collect import collect -import boutconfig as conf import itertools +import sys -import numpy as np +import numpy.testing as npt # Resolution in x and y -nlist = [1, 2, 4] +NLIST = [1, 2, 4] +MAXCORES = 8 +NSLICES = [1] -maxcores = 8 +build_and_log("FCI MMS test") -nslices = [1] +COLLECT_KW = dict(info=False, xguards=False, yguards=False, path="data") -success = True -build_and_log("FCI MMS test") +def run_case(nxpe: int, nype: int, mthread: int): + cmd = f"./fci_mpi NXPE={nxpe} NYPE={nype}" + print(f"Running command: {cmd}") + + _, out = launch_safe(cmd, nproc=nxpe * nype, mthread=mthread, pipe=True) + + # Save output to log file + with open(f"run.log.{nxpe}.{nype}.{nslice}.log", "w") as f: + f.write(out) + + +def test_case(nxpe: int, nype: int, mthread: int, ref: dict) -> bool: + run_case(nxpe, nype, mthread) + + failures = [] + + for name, val in ref.items(): + try: + npt.assert_allclose(val, collect(name, **COLLECT_KW)) + except AssertionError as e: + failures.append((nxpe, nype, name, e)) -for nslice in nslices: - for NXPE, NYPE in itertools.product(nlist, nlist): - if NXPE * NYPE > maxcores: + return failures + + +failures = [] + +for nslice in NSLICES: + # reference data! + run_case(1, 1, MAXCORES) + + ref = {} + for i in range(4): + for yp in range(1, nslice + 1): + for y in [-yp, yp]: + name = f"output_{i}_{y:+d}" + ref[name] = collect(name, **COLLECT_KW) + + for nxpe, nype in itertools.product(NLIST, NLIST): + if (nxpe, nype) == (1, 1): + # reference case, done above continue - args = f"NXPE={NXPE} NYPE={NYPE}" - # Command to run - cmd = f"./fci_mpi {args}" - - print(f"Running command: {cmd}") - - mthread = maxcores // (NXPE * NYPE) - # Launch using MPI - _, out = launch_safe(cmd, nproc=NXPE * NYPE, mthread=mthread, pipe=True) - - # Save output to log file - with open(f"run.log.{NXPE}.{NYPE}.{nslice}.log", "w") as f: - f.write(out) - - collect_kw = dict(info=False, xguards=False, yguards=False, path="data") - if NXPE == NYPE == 1: - # reference data! - ref = {} - for i in range(4): - for yp in range(1, nslice + 1): - for y in [-yp, yp]: - name = f"output_{i}_{y:+d}" - ref[name] = collect(name, **collect_kw) - else: - for name, val in ref.items(): - assert np.allclose(val, collect(name, **collect_kw)) + if nxpe * nype > MAXCORES: + continue + + mthread = MAXCORES // (nxpe * nype) + failures_ = test_case(nxpe, nype, mthread, ref) + failures.extend(failures_) + + +success = len(failures) == 0 +if success: + print("\nAll tests passed") +else: + print("\nSome tests failed:") + for nxpe, nype, name, error in failures: + print("----------") + print(f"case {nxpe=} {nype=} {name=}\n{error}") + +sys.exit(0 if success else 1) diff --git a/tests/integrated/test-fieldgroupComm/makefile b/tests/integrated/test-fieldgroupComm/makefile deleted file mode 100644 index f3215eccde..0000000000 --- a/tests/integrated/test-fieldgroupComm/makefile +++ /dev/null @@ -1,3 +0,0 @@ -BOUT_TOP = ../../../ -SOURCEC = test_fieldgroupcomm.cxx -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-globalfield/makefile b/tests/integrated/test-globalfield/makefile deleted file mode 100644 index fddd978535..0000000000 --- a/tests/integrated/test-globalfield/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_globalfield.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-griddata-yboundary-guards/makefile b/tests/integrated/test-griddata-yboundary-guards/makefile deleted file mode 100644 index f2ff47b18b..0000000000 --- a/tests/integrated/test-griddata-yboundary-guards/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_griddata.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-griddata/makefile b/tests/integrated/test-griddata/makefile deleted file mode 100644 index f2ff47b18b..0000000000 --- a/tests/integrated/test-griddata/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_griddata.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-gyro/makefile b/tests/integrated/test-gyro/makefile deleted file mode 100644 index 72dcff3424..0000000000 --- a/tests/integrated/test-gyro/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_gyro.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-include/makefile b/tests/integrated/test-include/makefile deleted file mode 100644 index 6b94f31f99..0000000000 --- a/tests/integrated/test-include/makefile +++ /dev/null @@ -1,4 +0,0 @@ - -BOUT_TOP = ../../.. - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-include/runtest b/tests/integrated/test-include/runtest index f70036a9e4..4fa8096c4b 100755 --- a/tests/integrated/test-include/runtest +++ b/tests/integrated/test-include/runtest @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash #requires: all_tests #Requires: not make diff --git a/tests/integrated/test-initial/makefile b/tests/integrated/test-initial/makefile deleted file mode 100644 index b314e92006..0000000000 --- a/tests/integrated/test-initial/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_initial.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-integrate/makefile b/tests/integrated/test-integrate/makefile deleted file mode 100644 index 2c1dc520b6..0000000000 --- a/tests/integrated/test-integrate/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_integrate.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-interchange-instability/makefile b/tests/integrated/test-interchange-instability/makefile deleted file mode 100644 index 23554affba..0000000000 --- a/tests/integrated/test-interchange-instability/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = 2fluid.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-interchange-instability/qsubcase.sh b/tests/integrated/test-interchange-instability/qsubcase.sh index 9713809a61..ba3e22e7fa 100755 --- a/tests/integrated/test-interchange-instability/qsubcase.sh +++ b/tests/integrated/test-interchange-instability/qsubcase.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash QSUB=mpich2sub # Common values are qsub, mpisub NP=4 diff --git a/tests/integrated/test-interpolate-z/makefile b/tests/integrated/test-interpolate-z/makefile deleted file mode 100644 index 5b925e1a97..0000000000 --- a/tests/integrated/test-interpolate-z/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_interpolate.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-interpolate/makefile b/tests/integrated/test-interpolate/makefile deleted file mode 100644 index 5b925e1a97..0000000000 --- a/tests/integrated/test-interpolate/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_interpolate.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-invertable-operator/makefile b/tests/integrated/test-invertable-operator/makefile deleted file mode 100644 index e0b6d92849..0000000000 --- a/tests/integrated/test-invertable-operator/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = invertable_operator.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-invpar/makefile b/tests/integrated/test-invpar/makefile deleted file mode 100644 index fc4b99517a..0000000000 --- a/tests/integrated/test-invpar/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_invpar.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-laplace-hypre3d/CMakeLists.txt b/tests/integrated/test-laplace-hypre3d/CMakeLists.txt index 2645c18c67..b09b416feb 100644 --- a/tests/integrated/test-laplace-hypre3d/CMakeLists.txt +++ b/tests/integrated/test-laplace-hypre3d/CMakeLists.txt @@ -7,4 +7,5 @@ bout_add_integrated_test(test-laplace-hypre3d data_slab_sol/BOUT.inp USE_RUNTEST REQUIRES BOUT_HAS_HYPRE + REQUIRES BOUT_RUN_ALL_TESTS ) diff --git a/tests/integrated/test-laplace-hypre3d/makefile b/tests/integrated/test-laplace-hypre3d/makefile deleted file mode 100644 index 88af7fb5e1..0000000000 --- a/tests/integrated/test-laplace-hypre3d/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-laplace3d.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-laplace-hypre3d/runtest b/tests/integrated/test-laplace-hypre3d/runtest index b50c5993b7..12ae54d9b7 100755 --- a/tests/integrated/test-laplace-hypre3d/runtest +++ b/tests/integrated/test-laplace-hypre3d/runtest @@ -13,7 +13,7 @@ test_directories = [ ("data_circular_core-sol", 1), ] -tolerance = 1.0e-6 +tolerance = 1.0e-4 build_and_log("Laplace 3D with Hypre") diff --git a/tests/integrated/test-laplace-petsc3d/makefile b/tests/integrated/test-laplace-petsc3d/makefile deleted file mode 100644 index 88af7fb5e1..0000000000 --- a/tests/integrated/test-laplace-petsc3d/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-laplace3d.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-laplace/makefile b/tests/integrated/test-laplace/makefile deleted file mode 100644 index a8a63959d3..0000000000 --- a/tests/integrated/test-laplace/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_laplace.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-laplace2/makefile b/tests/integrated/test-laplace2/makefile deleted file mode 100644 index a8a63959d3..0000000000 --- a/tests/integrated/test-laplace2/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_laplace.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-laplacexy-fv/makefile b/tests/integrated/test-laplacexy-fv/makefile deleted file mode 100644 index e7789b2203..0000000000 --- a/tests/integrated/test-laplacexy-fv/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-laplacexy.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-laplacexy-fv/test-laplacexy.cxx b/tests/integrated/test-laplacexy-fv/test-laplacexy.cxx index 8408f08c00..be2f993b31 100644 --- a/tests/integrated/test-laplacexy-fv/test-laplacexy.cxx +++ b/tests/integrated/test-laplacexy-fv/test-laplacexy.cxx @@ -23,18 +23,23 @@ * **************************************************************************/ -#include -#include -#include -#include -#include -#include +#include "bout/bout.hxx" +#include "bout/bout_types.hxx" +#include "bout/difops.hxx" +#include "bout/field2d.hxx" +#include "bout/initialprofiles.hxx" +#include "bout/invert/laplacexy.hxx" +#include "bout/options.hxx" +#include "bout/options_io.hxx" +#include "bout/output.hxx" + +#include int main(int argc, char** argv) { BoutInitialise(argc, argv); - LaplaceXY laplacexy; + auto laplacexy = LaplaceXY::create(); // Solving equations of the form // Div(A Grad_perp(f)) + B*f = rhs @@ -57,9 +62,9 @@ int main(int argc, char** argv) { Field2D rhs, rhs_check; rhs = Laplace_perpXY(a, f) + b * f; - laplacexy.setCoefs(a, b); + laplacexy->setCoefs(a, b); - sol = laplacexy.solve(rhs, 0.); + sol = laplacexy->solve(rhs, 0.); error = (f - sol) / f; absolute_error = f - sol; max_error = max(abs(absolute_error), true); diff --git a/tests/integrated/test-laplacexy-short/makefile b/tests/integrated/test-laplacexy-short/makefile deleted file mode 100644 index e7789b2203..0000000000 --- a/tests/integrated/test-laplacexy-short/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-laplacexy.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-laplacexy-short/test-laplacexy.cxx b/tests/integrated/test-laplacexy-short/test-laplacexy.cxx index 3486760810..7c284290b3 100644 --- a/tests/integrated/test-laplacexy-short/test-laplacexy.cxx +++ b/tests/integrated/test-laplacexy-short/test-laplacexy.cxx @@ -24,31 +24,39 @@ **************************************************************************/ #include -#include +#include #include +#include +#include +#include #include #include #include +#include +#include +#include + +#include int main(int argc, char** argv) { BoutInitialise(argc, argv); using bout::globals::mesh; - auto coords = mesh->getCoordinates(); + auto* coords = mesh->getCoordinates(); auto& opt = Options::root(); - LaplaceXY laplacexy; + auto laplacexy = LaplaceXY::create(); bool include_y_derivs = opt["laplacexy"]["include_y_derivs"]; // Solving equations of the form // Div(A Grad_perp(f)) + B*f = rhs // A*Laplace_perp(f) + Grad_perp(A).Grad_perp(f) + B*f = rhs - Field2D f, a, b, sol; - Field2D error, absolute_error; //Absolute value of relative error: abs((f - sol)/f) - BoutReal max_error; //Output of test + Field2D f; + Field2D a; + Field2D b; initial_profile("f", f); initial_profile("a", a); @@ -61,7 +69,8 @@ int main(int argc, char** argv) { //////////////////////////////////////////////////////////////////////////////////////// - Field2D rhs, rhs_check; + Field2D rhs; + Field2D rhs_check; if (include_y_derivs) { rhs = a * DC(Laplace_perp(f)) + DC(Grad_perp(a) * Grad_perp(f)) + b * f; } else { @@ -69,14 +78,14 @@ int main(int argc, char** argv) { a * DC(Delp2(f, CELL_DEFAULT, false)) + DC(coords->g11 * DDX(a) * DDX(f)) + b * f; } - laplacexy.setCoefs(a, b); + laplacexy->setCoefs(a, b); - sol = laplacexy.solve(rhs, 0.); - error = (f - sol) / f; - absolute_error = f - sol; - max_error = max(abs(absolute_error), true); + auto sol = laplacexy->solve(rhs, 0.); + const auto error = (f - sol) / f; + const auto absolute_error = f - sol; + const auto max_error = max(abs(absolute_error), true); - output << "Magnitude of maximum absolute error is " << max_error << endl; + output.write("Magnitude of maximum absolute error is {}\n", max_error); mesh->communicate(sol); if (include_y_derivs) { diff --git a/tests/integrated/test-laplacexy/makefile b/tests/integrated/test-laplacexy/makefile deleted file mode 100644 index e7789b2203..0000000000 --- a/tests/integrated/test-laplacexy/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-laplacexy.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-laplacexy/test-laplacexy.cxx b/tests/integrated/test-laplacexy/test-laplacexy.cxx index 3142d359b1..543274d37d 100644 --- a/tests/integrated/test-laplacexy/test-laplacexy.cxx +++ b/tests/integrated/test-laplacexy/test-laplacexy.cxx @@ -24,11 +24,19 @@ **************************************************************************/ #include -#include +#include #include +#include +#include +#include #include #include #include +#include +#include +#include + +#include using bout::globals::mesh; @@ -64,10 +72,10 @@ int main(int argc, char** argv) { rhs = a * Delp2(f, CELL_DEFAULT, false) + coords->g11 * DDX(a) * DDX(f) + b * f; } - LaplaceXY laplacexy; - laplacexy.setCoefs(a, b); + auto laplacexy = LaplaceXY::create(); + laplacexy->setCoefs(a, b); - Field2D solution = laplacexy.solve(rhs, 0.); + Field2D solution = laplacexy->solve(rhs, 0.); Field2D relative_error = (f - solution) / f; Field2D absolute_error = f - solution; BoutReal max_error = max(abs(absolute_error), true); diff --git a/tests/integrated/test-laplacexy2-hypre/makefile b/tests/integrated/test-laplacexy2-hypre/makefile deleted file mode 100644 index e7789b2203..0000000000 --- a/tests/integrated/test-laplacexy2-hypre/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-laplacexy.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-laplacexy2-hypre/test-laplacexy.cxx b/tests/integrated/test-laplacexy2-hypre/test-laplacexy.cxx index 2fb8a10777..e04de9c675 100644 --- a/tests/integrated/test-laplacexy2-hypre/test-laplacexy.cxx +++ b/tests/integrated/test-laplacexy2-hypre/test-laplacexy.cxx @@ -24,17 +24,22 @@ **************************************************************************/ #include -#include -#include +#include +#include +#include #include -#include +#include #include +#include +#include + +#include int main(int argc, char** argv) { BoutInitialise(argc, argv); - LaplaceXY2Hypre laplacexy; + auto laplacexy = LaplaceXYFactory::getInstance().create("hypre", nullptr); // Solving equations of the form // Div(A Grad_perp(f)) + B*f = rhs @@ -54,10 +59,10 @@ int main(int argc, char** argv) { Field2D rhs = Laplace_perpXY(a, f) + b * f; - laplacexy.setCoefs(a, b); + laplacexy->setCoefs(a, b); Field2D guess = 0.0; - Field2D sol = laplacexy.solve(rhs, guess); + Field2D sol = laplacexy->solve(rhs, guess); Field2D error = (f - sol) / f; // Absolute value of relative error: abs((f - sol)/f) Field2D absolute_error = abs(f - sol); diff --git a/tests/integrated/test-laplacexz/makefile b/tests/integrated/test-laplacexz/makefile deleted file mode 100644 index 49ac5e5baf..0000000000 --- a/tests/integrated/test-laplacexz/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test-laplacexz.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-multigrid_laplace/makefile b/tests/integrated/test-multigrid_laplace/makefile deleted file mode 100644 index 6eddb8b84d..0000000000 --- a/tests/integrated/test-multigrid_laplace/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test_multigrid_laplace.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-naulin-laplace/makefile b/tests/integrated/test-naulin-laplace/makefile deleted file mode 100644 index fb89ff2e71..0000000000 --- a/tests/integrated/test-naulin-laplace/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test_naulin_laplace.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-nonuniform/makefile b/tests/integrated/test-nonuniform/makefile deleted file mode 100644 index 0c6ba8b3a9..0000000000 --- a/tests/integrated/test-nonuniform/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_delp2.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-options-adios/makefile b/tests/integrated/test-options-adios/makefile deleted file mode 100644 index 7dbbce8736..0000000000 --- a/tests/integrated/test-options-adios/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test-options-adios.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-options-netcdf/makefile b/tests/integrated/test-options-netcdf/makefile deleted file mode 100644 index f9197480fb..0000000000 --- a/tests/integrated/test-options-netcdf/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test-options-netcdf.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-petsc_laplace/makefile b/tests/integrated/test-petsc_laplace/makefile deleted file mode 100644 index 58633ec996..0000000000 --- a/tests/integrated/test-petsc_laplace/makefile +++ /dev/null @@ -1,9 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test_petsc_laplace.cxx -TARGET = test_petsc_laplace - -CXXFLAGS +=-g - -include $(BOUT_TOP)/make.config - diff --git a/tests/integrated/test-petsc_laplace_MAST-grid/makefile b/tests/integrated/test-petsc_laplace_MAST-grid/makefile deleted file mode 100644 index 8a5ff1b27a..0000000000 --- a/tests/integrated/test-petsc_laplace_MAST-grid/makefile +++ /dev/null @@ -1,9 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test_petsc_laplace_MAST_grid.cxx -TARGET = test_petsc_laplace_MAST_grid - -CXXFLAGS +=-g - -include $(BOUT_TOP)/make.config - diff --git a/tests/integrated/test-region-iterator/makefile b/tests/integrated/test-region-iterator/makefile deleted file mode 100644 index fae70dbfa0..0000000000 --- a/tests/integrated/test-region-iterator/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_region_iterator.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-restart-io/makefile b/tests/integrated/test-restart-io/makefile deleted file mode 100644 index 4be85e426e..0000000000 --- a/tests/integrated/test-restart-io/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-restart-io.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-restarting/makefile b/tests/integrated/test-restarting/makefile deleted file mode 100644 index c1a416dcf9..0000000000 --- a/tests/integrated/test-restarting/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_restarting.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-slepc-solver/makefile b/tests/integrated/test-slepc-solver/makefile deleted file mode 100644 index 8fc1b74cf5..0000000000 --- a/tests/integrated/test-slepc-solver/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-slepc-solver.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-smooth/makefile b/tests/integrated/test-smooth/makefile deleted file mode 100644 index 141a214a50..0000000000 --- a/tests/integrated/test-smooth/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_smooth.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-snb/makefile b/tests/integrated/test-snb/makefile deleted file mode 100644 index 526313b1cf..0000000000 --- a/tests/integrated/test-snb/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_snb.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-solver/makefile b/tests/integrated/test-solver/makefile deleted file mode 100644 index 8d16dfc55c..0000000000 --- a/tests/integrated/test-solver/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test_solver.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-solver/test_solver.cxx b/tests/integrated/test-solver/test_solver.cxx index 2e4345c8cc..a24db71750 100644 --- a/tests/integrated/test-solver/test_solver.cxx +++ b/tests/integrated/test-solver/test_solver.cxx @@ -100,8 +100,7 @@ int main(int argc, char** argv) { root["imexbdf2"]["adaptive"] = true; root["imexbdf2"]["adaptRtol"] = 1.e-5; - root["petsc"]["nout"] = 10000; - root["petsc"]["output_step"] = end / 10000; + root["petsc"]["rtol"] = 1e-7; root["snes"]["adaptive"] = true; diff --git a/tests/integrated/test-squash/makefile b/tests/integrated/test-squash/makefile deleted file mode 100644 index cecff798ec..0000000000 --- a/tests/integrated/test-squash/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = squash.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-stopCheck-file/makefile b/tests/integrated/test-stopCheck-file/makefile deleted file mode 100644 index 2d2e644a9e..0000000000 --- a/tests/integrated/test-stopCheck-file/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_stopCheck.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-stopCheck/makefile b/tests/integrated/test-stopCheck/makefile deleted file mode 100644 index 2d2e644a9e..0000000000 --- a/tests/integrated/test-stopCheck/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_stopCheck.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-stopCheck/runtest b/tests/integrated/test-stopCheck/runtest index aa0920d087..5cb8f0f1fb 100755 --- a/tests/integrated/test-stopCheck/runtest +++ b/tests/integrated/test-stopCheck/runtest @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash make || exit diff --git a/tests/integrated/test-subdir/bar/makefile b/tests/integrated/test-subdir/bar/makefile deleted file mode 100644 index ffa825d218..0000000000 --- a/tests/integrated/test-subdir/bar/makefile +++ /dev/null @@ -1,6 +0,0 @@ -BOUT_TOP = ../../../.. - -SOURCEC = bar.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-subdir/fuu/makefile b/tests/integrated/test-subdir/fuu/makefile deleted file mode 100644 index 2c8332ee44..0000000000 --- a/tests/integrated/test-subdir/fuu/makefile +++ /dev/null @@ -1,6 +0,0 @@ -BOUT_TOP = ../../../.. - -SOURCEC = fuu.cxx -SOURCEH = $(SOURCEC:%.cxx=%.hxx) - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-subdir/makefile b/tests/integrated/test-subdir/makefile deleted file mode 100644 index ed52b47451..0000000000 --- a/tests/integrated/test-subdir/makefile +++ /dev/null @@ -1,10 +0,0 @@ -BOUT_TOP = ../../.. -SOURCEH = -SOURCEC = subdirs.cxx - -# make sure we extract the folder -# DIRS = fuu bar would work as well, but we want to make sure -# ../otherproject/fuu and /some/long/path/bar works as well ... -DIRS = fuu/ ././bar/ - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-twistshift-staggered/makefile b/tests/integrated/test-twistshift-staggered/makefile deleted file mode 100644 index 0018135bce..0000000000 --- a/tests/integrated/test-twistshift-staggered/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-twistshift.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-twistshift/makefile b/tests/integrated/test-twistshift/makefile deleted file mode 100644 index 0018135bce..0000000000 --- a/tests/integrated/test-twistshift/makefile +++ /dev/null @@ -1,5 +0,0 @@ -BOUT_TOP = ../../.. - -SOURCEC = test-twistshift.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-vec/makefile b/tests/integrated/test-vec/makefile deleted file mode 100644 index 75385e5460..0000000000 --- a/tests/integrated/test-vec/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = testVec.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-yupdown-weights/makefile b/tests/integrated/test-yupdown-weights/makefile deleted file mode 100644 index 4e3a173b0e..0000000000 --- a/tests/integrated/test-yupdown-weights/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_yupdown_weights.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test-yupdown/makefile b/tests/integrated/test-yupdown/makefile deleted file mode 100644 index 26728c595f..0000000000 --- a/tests/integrated/test-yupdown/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../../.. - -SOURCEC = test_yupdown.cxx - -include $(BOUT_TOP)/make.config diff --git a/tests/integrated/test_suite_make b/tests/integrated/test_suite_make deleted file mode 100755 index 36fe54225a..0000000000 --- a/tests/integrated/test_suite_make +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env sh - -./test_suite --make "$@" diff --git a/tests/unit/makefile b/tests/unit/makefile deleted file mode 100644 index 1264705559..0000000000 --- a/tests/unit/makefile +++ /dev/null @@ -1,114 +0,0 @@ -#################################################################### -# Tests -#################################################################### - -BOUT_TOP = ../.. - -BOUT_TEST_DIR = . - -GTEST_BASE = $(BOUT_TOP)/externalpackages/googletest -GTEST_DIR = $(GTEST_BASE)/googletest -GMOCK_DIR = $(GTEST_BASE)/googlemock - -GTEST_SOURCES = $(GTEST_DIR)/src/gtest-all.cc - -# Flags passed to the preprocessor. -# Set Google Test's header directory as a system directory, such that -# the compiler doesn't generate warnings in Google Test headers. -CXXFLAGS += -isystem ${GTEST_DIR}/include -I${GTEST_DIR} -I${BOUT_TEST_DIR} -CXXFLAGS += -isystem ${GMOCK_DIR}/include -I${GMOCK_DIR} - -# Flags passed to the C++ compiler. -CXXFLAGS += -g -Wall -Wextra -pthread - - -# All Google Test headers. Usually you shouldn't change this -# definition. -GTEST_HEADERS = $(GTEST_DIR)/include/gtest/*.h \ - $(GTEST_DIR)/include/gtest/internal/*.h - -all: serial_tests -include $(BOUT_TOP)/make.config - -LDFLAGS += -pthread - -# Existence of this file indicates that GTEST has been downloaded -GTEST_SENTINEL = $(GTEST_BASE)/README.md - -# House-keeping build targets. - -clean :: - @$(RM) -f gtest.a bout_test_main.a *.o $(TEST_OBJECTS) - -# Builds gtest.a and bout_test_main.a. - -# Download Google Test -$(GTEST_SENTINEL) : - @echo "Downloading Google Test" - git submodule update --init --recursive - -# For simplicity and to avoid depending on Google Test's -# implementation details, the dependencies specified below are -# conservative and not optimized. This is fine as Google Test -# compiles fast and for ordinary users its source rarely changes. -# -# Note: If the GoogleTest submodule has not been checked out when -# this makefile is run, then the list of .cc and .h files is not -# correctly captured. Since we will probably not be modifying googletest -# this rule just depends on the sentinel file. -gtest-all.o : $(GTEST_SENTINEL) - @echo " Compiling" $@ - @$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(BOUT_FLAGS) -c \ - $(GTEST_DIR)/src/gtest-all.cc - -gmock-all.o : $(GTEST_SENTINEL) - @echo " Compiling" $@ - @$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(BOUT_FLAGS) -c \ - $(GMOCK_DIR)/src/gmock-all.cc - -bout_test_main.o : $(GTEST_SENTINEL) $(BOUT_TEST_DIR)/bout_test_main.cxx - @echo " Compiling" $@ - @$(CXX) $(CPPFLAGS) -I$(GTEST_DIR) $(BOUT_INCLUDE) $(BOUT_FLAGS) -c $(@:.o=.cxx) - -gtest.a : gtest-all.o - @echo " Linking" $@ - @$(AR) $(ARFLAGS) $@ $^ - -gmock.a : gmock-all.o - @echo " Linking" $@ - @$(AR) $(ARFLAGS) $@ $^ - -bout_test_main.a : gtest-all.o gmock-all.o bout_test_main.o - @echo " Linking" $@ - @$(AR) $(ARFLAGS) $@ $^ - -$(TARGET): makefile $(BOUT_TOP)/make.config $(OBJ) $(SUB_LIBS) bout_test_main.a - @echo " Linking" $(TARGET) - @$(LD) $(LDFLAGS) -o $(TARGET) $(OBJ) $(BOUT_LIBS) $(SUB_LIBS) bout_test_main.a - -TEST_SOURCES = $(shell find $(BOUT_TEST_DIR) -type f -name "test_*.cxx" 2> /dev/null) -TEST_OBJECTS = $(TEST_SOURCES:%.cxx=%.o) - -$(TEST_OBJECTS): | $(GTEST_SENTINEL) - -serial_tests: makefile $(BOUT_TOP)/make.config $(OBJ) $(LIB) \ - $(SUB_LIBS) $(TEST_OBJECTS) bout_test_main.a - @echo " Linking tests" - @$(LD) -o $@ $(TEST_OBJECTS) bout_test_main.a $(LDFLAGS) $(BOUT_LIBS) $(SUB_LIBS) - -# Override this on the command line to print full output from the unit tests -QUIET ?= --gtest_brief=1 - -# Note: This depends on GTEST_SENTINEL, which checks out Google Test if not present -# The correct behaviour relies on the dependencies being checked in left-to-right order -# The GTEST_SENTINEL dependency cannot be added to the %.o target, since this results in the %.o -# target in make.config being used instead. -check: $(GTEST_SENTINEL) serial_tests - @echo "Running unit test" - @./serial_tests $(QUIET) $(GTEST_ARGS) - -# This is the same target as a make rule in make.config. Adding unmet dependencies here -# results in makefile reverting to the make.config version. -%.o: $(BOUT_TOP)/make.config %.cxx - @echo " Compiling " $(@:.o=.cxx) - @$(CXX) $(BOUT_INCLUDE) $(BOUT_FLAGS) -c $(@:.o=.cxx) -o $(@) diff --git a/tests/unit/src/test_bout++.cxx b/tests/unit/src/test_bout++.cxx index b31be16a67..cef518756c 100644 --- a/tests/unit/src/test_bout++.cxx +++ b/tests/unit/src/test_bout++.cxx @@ -70,7 +70,7 @@ class SignalHandlerTest : public ::testing::Test { using SignalHandlerTestDeathTest = SignalHandlerTest; -#if !defined(__NVCC__) +#if !defined(__NVCC__) and !defined(__FreeBSD__) TEST_F(SignalHandlerTestDeathTest, SegFault) { bout::experimental::setupSignalHandler(bout::experimental::defaultSignalHandler); // This test is *incredibly* expensive, maybe as much as 1s, so only test the one signal diff --git a/tests/unit/sys/test_options.cxx b/tests/unit/sys/test_options.cxx index 448b49fc19..725bbe1b04 100644 --- a/tests/unit/sys/test_options.cxx +++ b/tests/unit/sys/test_options.cxx @@ -1099,7 +1099,8 @@ value6 = 12 } TEST_F(OptionsTest, InvalidFormat) { - EXPECT_THROW(fmt::format("{:nope}", Options{}), fmt::format_error); + EXPECT_THROW([[maybe_unused]] auto none = fmt::format("{:nope}", Options{}), + fmt::format_error); } TEST_F(OptionsTest, FormatValue) { @@ -1439,3 +1440,14 @@ TEST_F(OptionsTest, BoolCompound) { ASSERT_TRUE(Options("true & !false").as()); ASSERT_TRUE(Options("2 > 1 & 2 < 3").as()); } + +TEST_F(OptionsTest, Iterate) { + Options option{{{"value1", 1}, {"value2", 2}}}; + + for (auto& [name, value] : option) { + value.force(value.as() + 1); + } + + ASSERT_EQ(option["value1"], 2); + ASSERT_EQ(option["value2"], 3); +} diff --git a/tests/unit/sys/test_timer.cxx b/tests/unit/sys/test_timer.cxx index 4ec934658d..7641c5f8cf 100644 --- a/tests/unit/sys/test_timer.cxx +++ b/tests/unit/sys/test_timer.cxx @@ -271,7 +271,7 @@ TEST(TimerTest, ListAllInfo) { using namespace ::testing; EXPECT_THAT(cout_capture.str(), HasSubstr("Timer name |")); - EXPECT_THAT(cout_capture.str(), ContainsRegex("one *| 0\\.\\d+ | 1 | 0\\.\\d+")); - EXPECT_THAT(cout_capture.str(), ContainsRegex("two *| 0 * | 2 | 0\\.\\d+")); + EXPECT_THAT(cout_capture.str(), ContainsRegex("one *| 0\\.[0-9]+ | 1 | 0\\.[0-9]+")); + EXPECT_THAT(cout_capture.str(), ContainsRegex("two *| 0 * | 2 | 0\\.[0-9]+")); } #endif diff --git a/tools/pdb2idl/make.config.in b/tools/pdb2idl/make.config.in deleted file mode 100644 index 36c97e7789..0000000000 --- a/tools/pdb2idl/make.config.in +++ /dev/null @@ -1,19 +0,0 @@ -# configuration file for PDB2IDL - -CFLAGS = @CFLAGS@ -LDFLAGS = @LDFLAGS@ - -CC = @CC@ -LD = @LD@ - -# Set the location of the PACT installation -PACT = @PACT@ - -# IDL external library -IDLPATH = @IDLPATH@ - -#################################### -# Do not need to alter this section - -INCLUDE = -I$(PACT)/include -I$(IDLPATH) -LIB = -L$(PACT)/lib -lpdb -lpml -lscore diff --git a/tools/pylib/_boutpp_build/backend.py b/tools/pylib/_boutpp_build/backend.py index 3df29d276d..31a4694d10 100755 --- a/tools/pylib/_boutpp_build/backend.py +++ b/tools/pylib/_boutpp_build/backend.py @@ -35,8 +35,8 @@ def getversion(): version = os.environ["BOUT_PRETEND_VERSION"] return version - _bout_previous_version = "v5.1.1" - _bout_next_version = "v5.2.0" + _bout_previous_version = "v5.2.0" + _bout_next_version = "v5.2.1" try: try: @@ -216,9 +216,16 @@ def build_sdist(sdist_directory, config_settings=None): f"""Metadata-Version: 2.1 Name: {pkgname} Version: {getversion()} -License-File: COPYING """ ) + with open("LICENSE") as src: + pre = "License: " + for l in src: + f.write(f"{pre}{l}") + pre = " " + f.write("Description-Content-Type: text/markdown\n\n") + with open("README.md") as src: + f.write(src.read()) run( f"tar --append -f {sdist_directory}/{fname} _version.txt --xform='s\\_version.txt\\{prefix}/_version.txt\\'" ) diff --git a/tools/pylib/boutconfig/__init__.py.cin b/tools/pylib/boutconfig/__init__.py.cin index d031d599b5..b65b25a75a 100644 --- a/tools/pylib/boutconfig/__init__.py.cin +++ b/tools/pylib/boutconfig/__init__.py.cin @@ -31,6 +31,7 @@ config = { "has_fftw": "@BOUT_HAS_FFTW@", "petsc_has_sundials": "@PETSC_HAS_SUNDIALS@", "metric_type": "@BOUT_METRIC_TYPE@", + "has_hypre": "@BOUT_HAS_HYPRE@", } for k, v in config.items(): diff --git a/tools/vagrant/README.md b/tools/vagrant/README.md deleted file mode 100644 index 0adb67fa67..0000000000 --- a/tools/vagrant/README.md +++ /dev/null @@ -1,12 +0,0 @@ -This is a basic vagrant config which you can use to compile and run BOUT++ on your local machine. For more info on vagrant see https://www.vagrantup.com/. - -To use it, cd into this directory and run: - - vagrant up # this creates the VM, installs BOUT including dependencies and runs all the tests. - vagrant ssh # logs in to the VM. - -At this point you should be able to run one of the examples: - - cd BOUT/examples/conduction # find a simple example. - make # compile the example. - mpirun -np 2 ./conduction # run the example. diff --git a/tools/vagrant/Vagrantfile b/tools/vagrant/Vagrantfile deleted file mode 100644 index 0b0b3bc49c..0000000000 --- a/tools/vagrant/Vagrantfile +++ /dev/null @@ -1,9 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -VAGRANTFILE_API_VERSION = "2" - -Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| - config.vm.box = "ubuntu/trusty64" - config.vm.provision :shell, path: "bootstrap.sh" -end diff --git a/tools/vagrant/bootstrap.sh b/tools/vagrant/bootstrap.sh deleted file mode 100644 index 6737eac53c..0000000000 --- a/tools/vagrant/bootstrap.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash - -# install dependencies -apt-get update -apt-get install -y mpich2 libmpich2-dev -apt-get install -y libfftw3-dev libnetcdf-dev -apt-get install -y g++ make -apt-get install -y python-scipy - -# get the bout++ code -apt-get install -y git -rm -rf BOUT -git clone https://github.com/bendudson/BOUT.git - -# environment variables for both this session and the vagrant user -echo "export IDL_PATH=$(pwd)/BOUT/tools/idllib" >> $(pwd)/.bashrc -echo "export PYTHONPATH=$(pwd)/BOUT/tools/pylib/:$PYTHONPATH" >> $(pwd)/.bashrc -source $(pwd)/.bashrc -export IDL_PATH=$(pwd)/BOUT/tools/idllib -export PYTHONPATH=$(pwd)/BOUT/tools/pylib/:$PYTHONPATH - -# configure bout++ -cd BOUT -./configure -make -cd examples -./test_suite - -# set owner to vagrant user so compilation works -cd ../.. -chown -R vagrant:vagrant BOUT