Skip to content

Field3DParallel + more FCI changes#3197

Open
dschwoerer wants to merge 440 commits intonextfrom
f3dwy
Open

Field3DParallel + more FCI changes#3197
dschwoerer wants to merge 440 commits intonextfrom
f3dwy

Conversation

@dschwoerer
Copy link
Contributor

@dschwoerer dschwoerer commented Nov 6, 2025

Here a summary of the changes:

Field3DParallel

A Field3DParallel is essentially a Field3D, that preserves the parallel slices.
This allows to avoid unnecessary computation of of parallel fields, that are not needed.
It also ensures parallel slices are present (for FCI) when later parallel derivatives are computed.
So any function that will call DDY later on, can change the signature to Field3DParallel to declare that parallel slices need to be present for FCI.

New Y-Boundary Operators

Custom sheath boundary conditions can now be implemented using an abstraction. The documentation is on RTD
That allows having one code path for FCI and FA, for upper and lower sheath BC, all in one place.

Various small fixups

loadParallelMetrics

For FCI the parallel slices of the metric components are loaded, as they are sometimes needed.
This makes FCI essentially 3D only.
There is now also the option to say a field is not allow to compute the parallel slices, to avoid overwriting them: allowCalcParallelSlices.

Tracking on failure

Only if the simulation fails to evolve (Currently euler and pvode only):
The different components of timederivate are dumped to a BOUT.debug.*.nc which can be handy for figuring out which term is causing the instability. No more having to re-run the simulation with some terms disabled to debug such issues. This causes (an unkown) memory overhead - but ONLY if the solver has failed already.

More names of parallel boundary region + cleanup of code

Support things like bndry_par_xin or bndry_par_yup.

Add monotonichermitespline for all cases

Merged into hermitespline and works also in parallel.

Support several parallel slices for FCI

MYG=2 is now supported.

Using a local set for each thread ensures we do not need a mutex for
adding data, at the cost of having to merge the different sets later.
We want to skip sending if there is no data for this process ...
The result needs to be well understood, as the indices are a mix of
local and global indices, as we need to access non-local data.
This allows to also run the tests with 3D metrics.

It also tightens the tollerances, as this is a regression test.

Also removing the preconditioner is needed.
This reverts commit 8485353.

The parallel metric components are loaded, thus we can take meaningful
derivatives in y-direction.
Directly iterate over the points
This avoids errors in the MMS tests
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 25 out of 68. Check the log or trigger a new build to see more.

template <class ind>
struct XYZ2Ind {
const int nx;
const int ny;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member 'ny' of type 'const int' is const qualified [cppcoreguidelines-avoid-const-or-ref-data-members]

  const int ny;
            ^

struct XYZ2Ind {
const int nx;
const int ny;
const int nz;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member 'nz' of type 'const int' is const qualified [cppcoreguidelines-avoid-const-or-ref-data-members]

  const int nz;
            ^

const int ny;
const int nz;
ind convert(const int x, const int y, const int z) const {
return {z + (y + x * ny) * nz, ny, nz};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

Suggested change
return {z + (y + x * ny) * nz, ny, nz};
return {z + ((y + x * ny) * nz), ny, nz};


GlobalField3DAccessInstance(const GlobalField3DAccess* gfa,
const std::vector<BoutReal>&& data)
: gfa(*gfa), data(std::move(data)){};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: std::move of the const variable 'data' has no effect; remove std::move() or make the variable non-const [performance-move-const-arg]

Suggested change
: gfa(*gfa), data(std::move(data)){};
: gfa(*gfa), data(data){};

: gfa(*gfa), data(std::move(data)){};

private:
const GlobalField3DAccess& gfa;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member 'gfa' of type 'const GlobalField3DAccess &' is a reference [cppcoreguidelines-avoid-const-or-ref-data-members]

  const GlobalField3DAccess& gfa;
                             ^

int cnt = 0;
for ([[maybe_unused]] auto dummy : reqs) {
int ind{0};
auto ret = MPI_Waitany(reqs.size(), &reqs[0], &ind, MPI_STATUS_IGNORE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]

Suggested change
auto ret = MPI_Waitany(reqs.size(), &reqs[0], &ind, MPI_STATUS_IGNORE);
auto ret = MPI_Waitany(reqs.size(), reqs.data(), &ind, MPI_STATUS_IGNORE);

int cnt = 0;
for ([[maybe_unused]] auto dummy : reqs) {
int ind{0};
auto ret = MPI_Waitany(reqs.size(), &reqs[0], &ind, MPI_STATUS_IGNORE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'size_type' (aka 'unsigned long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]

      auto ret = MPI_Waitany(reqs.size(), &reqs[0], &ind, MPI_STATUS_IGNORE);
                             ^

sendBufferSize += toSendSizes[ind];
toSend[ind].resize(toSendSizes[ind], -1);

ret = MPI_Irecv(static_cast<void*>(toSend[ind].data()), toSend[ind].size(), MPI_INT,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'size_type' (aka 'unsigned long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]

      ret = MPI_Irecv(static_cast<void*>(toSend[ind].data()), toSend[ind].size(), MPI_INT,
                                                              ^

ASSERT0(ret == MPI_SUCCESS);
}
for (size_t proc = 0; proc < toGet.size(); ++proc) {
if (toGet[proc].size() != 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]

Suggested change
if (toGet[proc].size() != 0) {
if (!toGet[proc].empty()) {
Additional context

/usr/include/c++/15/bits/stl_vector.h:1222: method 'vector'::empty() defined here

      empty() const _GLIBCXX_NOEXCEPT
      ^

for (size_t proc = 0; proc < toGet.size(); ++proc) {
if (toGet[proc].size() != 0) {
const auto ret = MPI_Send(static_cast<void*>(toGet[proc].data()),
toGet[proc].size(), MPI_INT, proc, 666 * 666, comm);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'size_t' (aka 'unsigned long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]

                                  toGet[proc].size(), MPI_INT, proc, 666 * 666, comm);
                                                               ^

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 25 out of 68. Check the log or trigger a new build to see more.

template <class ind>
struct XYZ2Ind {
const int nx;
const int ny;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member 'ny' of type 'const int' is const qualified [cppcoreguidelines-avoid-const-or-ref-data-members]

  const int ny;
            ^

struct XYZ2Ind {
const int nx;
const int ny;
const int nz;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member 'nz' of type 'const int' is const qualified [cppcoreguidelines-avoid-const-or-ref-data-members]

  const int nz;
            ^

const int ny;
const int nz;
ind convert(const int x, const int y, const int z) const {
return {z + (y + x * ny) * nz, ny, nz};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: '*' has higher precedence than '+'; add parentheses to explicitly specify the order of operations [readability-math-missing-parentheses]

Suggested change
return {z + (y + x * ny) * nz, ny, nz};
return {z + ((y + x * ny) * nz), ny, nz};


GlobalField3DAccessInstance(const GlobalField3DAccess* gfa,
const std::vector<BoutReal>&& data)
: gfa(*gfa), data(std::move(data)){};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: std::move of the const variable 'data' has no effect; remove std::move() or make the variable non-const [performance-move-const-arg]

Suggested change
: gfa(*gfa), data(std::move(data)){};
: gfa(*gfa), data(data){};

: gfa(*gfa), data(std::move(data)){};

private:
const GlobalField3DAccess& gfa;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member 'gfa' of type 'const GlobalField3DAccess &' is a reference [cppcoreguidelines-avoid-const-or-ref-data-members]

  const GlobalField3DAccess& gfa;
                             ^

int cnt = 0;
for ([[maybe_unused]] auto dummy : reqs) {
int ind{0};
auto ret = MPI_Waitany(reqs.size(), &reqs[0], &ind, MPI_STATUS_IGNORE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: 'data' should be used for accessing the data pointer instead of taking the address of the 0-th element [readability-container-data-pointer]

Suggested change
auto ret = MPI_Waitany(reqs.size(), &reqs[0], &ind, MPI_STATUS_IGNORE);
auto ret = MPI_Waitany(reqs.size(), reqs.data(), &ind, MPI_STATUS_IGNORE);

int cnt = 0;
for ([[maybe_unused]] auto dummy : reqs) {
int ind{0};
auto ret = MPI_Waitany(reqs.size(), &reqs[0], &ind, MPI_STATUS_IGNORE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'size_type' (aka 'unsigned long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]

      auto ret = MPI_Waitany(reqs.size(), &reqs[0], &ind, MPI_STATUS_IGNORE);
                             ^

sendBufferSize += toSendSizes[ind];
toSend[ind].resize(toSendSizes[ind], -1);

ret = MPI_Irecv(static_cast<void*>(toSend[ind].data()), toSend[ind].size(), MPI_INT,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'size_type' (aka 'unsigned long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]

      ret = MPI_Irecv(static_cast<void*>(toSend[ind].data()), toSend[ind].size(), MPI_INT,
                                                              ^

ASSERT0(ret == MPI_SUCCESS);
}
for (size_t proc = 0; proc < toGet.size(); ++proc) {
if (toGet[proc].size() != 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]

Suggested change
if (toGet[proc].size() != 0) {
if (!toGet[proc].empty()) {
Additional context

/usr/include/c++/15/bits/stl_vector.h:1222: method 'vector'::empty() defined here

      empty() const _GLIBCXX_NOEXCEPT
      ^

for (size_t proc = 0; proc < toGet.size(); ++proc) {
if (toGet[proc].size() != 0) {
const auto ret = MPI_Send(static_cast<void*>(toGet[proc].data()),
toGet[proc].size(), MPI_INT, proc, 666 * 666, comm);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'size_t' (aka 'unsigned long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]

                                  toGet[proc].size(), MPI_INT, proc, 666 * 666, comm);
                                                               ^

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

There were too many comments to post at once. Showing the first 25 out of 43. Check the log or trigger a new build to see more.

for (size_t proc = 0; proc < toGet.size(); ++proc) {
if (toGet[proc].size() != 0) {
const auto ret = MPI_Send(static_cast<void*>(toGet[proc].data()),
toGet[proc].size(), MPI_INT, proc, 666 * 666, comm);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'size_type' (aka 'unsigned long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]

                                  toGet[proc].size(), MPI_INT, proc, 666 * 666, comm);
                                  ^

std::set<int> ids;
std::map<int, int> mapping;
bool is_setup{false};
const fci_comm::globalToLocal1D g2lx;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member 'g2lx' of type 'const fci_comm::globalToLocal1D' is const qualified [cppcoreguidelines-avoid-const-or-ref-data-members]

  const fci_comm::globalToLocal1D g2lx;
                                  ^

std::map<int, int> mapping;
bool is_setup{false};
const fci_comm::globalToLocal1D g2lx;
const fci_comm::globalToLocal1D g2ly;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member 'g2ly' of type 'const fci_comm::globalToLocal1D' is const qualified [cppcoreguidelines-avoid-const-or-ref-data-members]

  const fci_comm::globalToLocal1D g2ly;
                                  ^

bool is_setup{false};
const fci_comm::globalToLocal1D g2lx;
const fci_comm::globalToLocal1D g2ly;
const fci_comm::globalToLocal1D g2lz;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member 'g2lz' of type 'const fci_comm::globalToLocal1D' is const qualified [cppcoreguidelines-avoid-const-or-ref-data-members]

  const fci_comm::globalToLocal1D g2lz;
                                  ^

const fci_comm::globalToLocal1D g2lz;

public:
const fci_comm::XYZ2Ind<Ind3D> xyzl;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: member 'xyzl' of type 'const fci_comm::XYZ2Ind' (aka 'const XYZ2Ind<SpecificInd<IND_TYPE::IND_3D>>') is const qualified [cppcoreguidelines-avoid-const-or-ref-data-members]

  const fci_comm::XYZ2Ind<Ind3D> xyzl;
                                 ^

(dump_at_time >= 0 && std::abs(dump_at_time - curtime) < dt) || dump_at_time < -3;
std::unique_ptr<Options> debug_ptr;
if (dump_now) {
debug_ptr = std::make_unique<Options>();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::make_unique" is directly included [misc-include-cleaner]

    debug_ptr = std::make_unique<Options>();
                     ^

debug_ptr = std::make_unique<Options>();
Options& debug = *debug_ptr;
for (auto& f : f3d) {
f.F_var->enableTracking(fmt::format("ddt_{:s}", f.name), debug);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "fmt::format" is directly included [misc-include-cleaner]

src/solver/impls/euler/euler.cxx:2:

+ #include "fmt/format.h"

Options& debug = *debug_ptr;
Mesh* mesh{nullptr};
for (auto& f : f3d) {
saveParallel(debug, f.name, *f.var);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "saveParallel" is directly included [misc-include-cleaner]

      saveParallel(debug, f.name, *f.var);
      ^

}

const std::string outnumber =
dump_at_time < -3 ? fmt::format(".{}", debug_counter++) : "";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "fmt::format" is directly included [misc-include-cleaner]

        dump_at_time < -3 ? fmt::format(".{}", debug_counter++) : "";
                                 ^

const std::string outnumber =
dump_at_time < -3 ? fmt::format(".{}", debug_counter++) : "";
const std::string outname =
fmt::format("{}/BOUT.debug{}.{}.nc",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "fmt::format" is directly included [misc-include-cleaner]

        fmt::format("{}/BOUT.debug{}.{}.nc",
             ^

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions


/// Some implementations can also implement the forward operator for testing
/// and debugging
virtual FieldPerp forward(const FieldPerp& f);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function 'Laplacian::forward' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name]

  virtual FieldPerp forward(const FieldPerp& f);
                    ^
Additional context

src/invert/laplace/invert_laplace.cxx:283: the definition seen here

FieldPerp Laplacian::forward([[maybe_unused]] const FieldPerp& b) {
                     ^

include/bout/invert_laplace.hxx:263: differing parameters are named here: ('f'), in definition: ('b')

  virtual FieldPerp forward(const FieldPerp& f);
                    ^

/// Some implementations can also implement the forward operator for testing
/// and debugging
virtual FieldPerp forward(const FieldPerp& f);
virtual Field3D forward(const Field3D& f);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function 'Laplacian::forward' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name]

  virtual Field3D forward(const Field3D& f);
                  ^
Additional context

src/invert/laplace/invert_laplace.cxx:256: the definition seen here

Field3D Laplacian::forward(const Field3D& b) {
                   ^

include/bout/invert_laplace.hxx:264: differing parameters are named here: ('f'), in definition: ('b')

  virtual Field3D forward(const Field3D& f);
                  ^

void pvode_load_data_f3d(const std::vector<bool>& evolve_bndrys,
std::vector<Field3D>& ffs, const BoutReal* udata) {
int p = 0;
Mesh* mesh = ffs[0].getMesh();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: pointee of variable 'mesh' of type 'Mesh *' can be declared 'const' [misc-const-correctness]

Suggested change
Mesh* mesh = ffs[0].getMesh();
Mesh const* mesh = ffs[0].getMesh();

const BoutReal hmax(
(*options)["max_timestep"].doc("Maximum internal timestep").withDefault(-1.));
if (hmax > 0) {
ropt[HMAX] = hmax;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "pvode::HMAX" is directly included [misc-include-cleaner]

      ropt[HMAX] = hmax;
           ^

const BoutReal hmin(
(*options)["min_timestep"].doc("Minimum internal timestep").withDefault(-1.));
if (hmin > 0) {
ropt[HMIN] = hmin;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "pvode::HMIN" is directly included [misc-include-cleaner]

      ropt[HMIN] = hmin;
           ^

////////////// 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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "Field3DParallel" is directly included [misc-include-cleaner]

Field3D DDY(const Field3DParallel& f, CELL_LOC outloc, const std::string& method,
                  ^

ASSERT0(tosave.isAllocated());
opt[name] = tosave;
for (size_t i0 = 1; i0 <= tosave.numberParallelSlices(); ++i0) {
for (int i : {i0, -i0}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'unsigned long' to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]

    for (int i : {i0, -i0}) {
               ^

Field3D v{FieldFactory::get()->create3D("v", Options::getRoot(), mesh)};

// Communicate to calculate parallel transform.
if constexpr (bout::build::use_metric_3d) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "bout::build::use_metric_3d" is directly included [misc-include-cleaner]

tests/MMS/spatial/finite-volume/fv_mms.cxx:1:

- #include "bout/difops.hxx"
+ #include "bout/build_config.hxx"
+ #include "bout/difops.hxx"

#include <fmt/format.h>
#include <vector>

#include <fmt/format.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: duplicate include [readability-duplicate-include]

tests/integrated/test-fci-boundary/get_par_bndry.cxx:10:

- 
- #include <fmt/format.h>


#include <fmt/format.h>

#include <vector>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: duplicate include [readability-duplicate-include]

tests/integrated/test-fci-boundary/get_par_bndry.cxx:12:

- 
- #include <vector>

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

class NewBoundaryRegionY {
public:
NewBoundaryRegionY(Mesh* mesh, bool lower, RangeIterator r)
: mesh(mesh), lower(lower), r(std::move(r)) {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::move" is directly included [misc-include-cleaner]

include/bout/boundary_iterator.hxx:15:

+ #include <utility>

@@ -66,7 +68,8 @@ public:
*/
Field2D(Mesh* localmesh = nullptr, CELL_LOC location_in = CELL_CENTRE,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function 'Field2D::Field2D' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name]

  Field2D(Mesh* localmesh = nullptr, CELL_LOC location_in = CELL_CENTRE,
  ^
Additional context

src/field/field2d.cxx:43: the definition seen here

Field2D::Field2D(Mesh* localmesh, CELL_LOC location_in, DirectionTypes directions_in,
         ^

include/bout/field2d.hxx:68: differing parameters are named here: ('region'), in definition: ('UNUSED_regionID')

  Field2D(Mesh* localmesh = nullptr, CELL_LOC location_in = CELL_CENTRE,
  ^

}
return Field3DParallel(*this, true);
}
const Field3DParallel Field3D::asField3DParallel() const {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: return type 'const Field3DParallel' is 'const'-qualified at the top level, which may reduce code readability without improving const correctness [readability-const-return-type]

include/bout/field3d.hxx:550:

-   inline const Field3DParallel asField3DParallel() const;
+   inline Field3DParallel asField3DParallel() const;
Suggested change
const Field3DParallel Field3D::asField3DParallel() const {
Field3DParallel Field3D::asField3DParallel() const {

switch (mode) {
case SheathLimitMode::limit_free:
case SheathLimitMode::exponential_free:
fp = SQ(fc) / fm; // Exponential
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "SQ" is directly included [misc-include-cleaner]

include/bout/parallel_boundary_region.hxx:15:

- #include <bout/field3d.hxx>
+ #include "bout/utils.hxx"
+ #include <bout/field3d.hxx>


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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: conditional operator is used as sub-expression of parent conditional operator, refrain from using nested conditional operators [readability-avoid-nested-conditional-operator]

                                 : (mode == SheathLimitMode::linear_free ? 0 : 1);
                                    ^
Additional context

include/bout/parallel_boundary_region.hxx:288: parent conditional operator here

    const auto fac = valid() > 0 ? limitFreeScale(yprev(f), ythis(f), mode)
                     ^


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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: conditional operator is used as sub-expression of parent conditional operator, refrain from using nested conditional operators [readability-avoid-nested-conditional-operator]

                                 : (mode == SheathLimitMode::linear_free ? 0 : 1);
                                    ^
Additional context

include/bout/parallel_boundary_region.hxx:296: parent conditional operator here

    const auto fac = valid() > 0 ? limitFreeScale(yprev(f), ythis(f), mode)
                     ^


class BoundaryRegionPar : public BoundaryRegionBase {
public:
BoundaryRegionPar(const std::string& name, int dir, Mesh* passmesh)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::string" is directly included [misc-include-cleaner]

include/bout/parallel_boundary_region.hxx:12:

- #include <vector>
+ #include <string>
+ #include <vector>

}
o_ids.clear();
#endif
toGet.resize(g2lx.npe * g2ly.npe * g2lz.npe);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: performing an implicit widening conversion to type 'size_type' (aka 'unsigned long') of a multiplication performed in type 'int' [bugprone-implicit-widening-of-multiplication-result]

    toGet.resize(g2lx.npe * g2ly.npe * g2lz.npe);
                 ^
Additional context

src/mesh/parallel/fci_comm.hxx:147: make conversion explicit to silence this warning

    toGet.resize(g2lx.npe * g2ly.npe * g2lz.npe);
                 ^

src/mesh/parallel/fci_comm.hxx:147: perform multiplication in a wider type

    toGet.resize(g2lx.npe * g2ly.npe * g2lz.npe);
                 ^

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions


#include <functional>
#include <utility>

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: included header utility is not used directly [misc-include-cleaner]

Suggested change

}

void limit_at_least(Field3D& f, BoutReal value) const {
ynext(f) = std::max(ynext(f), value);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: no header providing "std::max" is directly included [misc-include-cleaner]

include/bout/boundary_iterator.hxx:13:

- #include <functional>
+ #include <algorithm>
+ #include <functional>

@@ -66,7 +68,8 @@ public:
*/
Field2D(Mesh* localmesh = nullptr, CELL_LOC location_in = CELL_CENTRE,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function 'Field2D::Field2D' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name]

  Field2D(Mesh* localmesh = nullptr, CELL_LOC location_in = CELL_CENTRE,
  ^
Additional context

src/field/field2d.cxx:45: the definition seen here

Field2D::Field2D(Mesh* localmesh, CELL_LOC location_in, DirectionTypes directions_in,
         ^

include/bout/field2d.hxx:68: differing parameters are named here: ('region'), in definition: ('UNUSED_regionID')

  Field2D(Mesh* localmesh = nullptr, CELL_LOC location_in = CELL_CENTRE,
  ^


/// Some implementations can also implement the forward operator for testing
/// and debugging
virtual FieldPerp forward(const FieldPerp& f);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function 'Laplacian::forward' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name]

  virtual FieldPerp forward(const FieldPerp& f);
                    ^
Additional context

src/invert/laplace/invert_laplace.cxx:284: the definition seen here

FieldPerp Laplacian::forward([[maybe_unused]] const FieldPerp& b) {
                     ^

include/bout/invert_laplace.hxx:263: differing parameters are named here: ('f'), in definition: ('b')

  virtual FieldPerp forward(const FieldPerp& f);
                    ^

/// Some implementations can also implement the forward operator for testing
/// and debugging
virtual FieldPerp forward(const FieldPerp& f);
virtual Field3D forward(const Field3D& f);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: function 'Laplacian::forward' has a definition with different parameter names [readability-inconsistent-declaration-parameter-name]

  virtual Field3D forward(const Field3D& f);
                  ^
Additional context

src/invert/laplace/invert_laplace.cxx:257: the definition seen here

Field3D Laplacian::forward(const Field3D& b) {
                   ^

include/bout/invert_laplace.hxx:264: differing parameters are named here: ('f'), in definition: ('b')

  virtual Field3D forward(const Field3D& f);
                  ^

}
Coordinates::FieldMetric& Coordinates::Jxz_yhigh() {
if (!_jxz_yhigh.has_value()) {
_compute_Jxz_cell_faces();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unchecked access to optional value [bugprone-unchecked-optional-access]

  return *_jxz_yhigh;
          ^

}
Coordinates::FieldMetric& Coordinates::Jxz() {
if (!_jxz_centre.has_value()) {
_compute_Jxz_cell_faces();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unchecked access to optional value [bugprone-unchecked-optional-access]

  return *_jxz_centre;
          ^

}
o_ids.clear();
#endif
toGet.resize(static_cast<size_type>(g2lx.npe * g2ly.npe * g2lz.npe));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: either cast from 'int' to 'size_t' (aka 'unsigned long') is ineffective, or there is loss of precision before the conversion [bugprone-misplaced-widening-cast]

    toGet.resize(static_cast<size_type>(g2lx.npe * g2ly.npe * g2lz.npe));
                 ^

}
o_ids.clear();
#endif
toGet.resize(static_cast<size_type>(g2lx.npe * g2ly.npe * g2lz.npe));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: unknown type name 'size_type'; did you mean 'size_t'? [clang-diagnostic-error]

Suggested change
toGet.resize(static_cast<size_type>(g2lx.npe * g2ly.npe * g2lz.npe));
toGet.resize(static_cast<size_t>(g2lx.npe * g2ly.npe * g2lz.npe));
Additional context

/usr/lib/llvm-21/lib/clang/21/include/__stddef_size_t.h:17: 'size_t' declared here

typedef __SIZE_TYPE__ size_t;
                      ^

int cnt = 0;
for ([[maybe_unused]] auto* dummy : reqs) {
int ind{0};
auto ret = MPI_Waitany(reqs.size(), reqs.data(), &ind, MPI_STATUS_IGNORE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: narrowing conversion from 'size_type' (aka 'unsigned long') to signed type 'int' is implementation-defined [bugprone-narrowing-conversions]

      auto ret = MPI_Waitany(reqs.size(), reqs.data(), &ind, MPI_STATUS_IGNORE);
                             ^

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants