Commit 7da0b5be authored by Mark Olesen's avatar Mark Olesen Committed by Andrew Heather
Browse files

ENH: trap negative blockMesh expansions and treat as their inverse

- A negative expansion ratio is geometrically invalid and will
  normally cause issues (FatalError).
  However, we can trap this type of input and interpret it as the
  inverse expansion ratio - ie, the expansion ratio in the opposite
  direction. This can be especially convenient when generating a blockMesh
  with a symmetrical expansion. It permits using the same expansion
  ratio (with a sign change) instead of providing the reciprocal values
  manually.

COMP: revert demand-driven point creation in blockMesh (db9b35b5)

- appears to have caused a dangling reference on some systems

ENH: add a lightweight ijkAddressing class

- it can be used for an i-j-k to linear lookup of meshes or fields,
  where applicable.
parent 1dc9e7c4
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::ijkAddressing
Description
A simple i-j-k (row-major order) to linear addressing.
SourceFiles
ijkAddressingI.H
\*---------------------------------------------------------------------------*/
#ifndef ijkAddressing_H
#define ijkAddressing_H
#include "labelVector.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ijkAddressing Declaration
\*---------------------------------------------------------------------------*/
class ijkAddressing
{
// Private Data
//- The number of cells in the i,j,k directions.
labelVector sizes_;
public:
// Constructors
//- Construct zero-size addressing
inline ijkAddressing();
//- Construct with addressing
inline explicit ijkAddressing(const labelVector& ijk);
//- Construct with addressing components
inline ijkAddressing(const label ni, const label nj, const label nk);
// Member Functions
// Access
//- Return the i,j,k addressing sizes
inline const labelVector& sizes() const;
//- Return the i,j,k addressing sizes for modification
inline labelVector& sizes();
//- Return the total i*j*k size
inline label size() const;
//- Addressing is considered empty if any component is zero
inline bool empty() const;
//- Reset to (0,0,0) sizing
inline void clear();
//- Change the sizing parameters
inline void reset(const label ni, const label nj, const label nk);
//- Linear addressing index (offset) for an i,j,k position.
inline label index(const label i, const label j, const label k) const;
// Checks
//- Check indices are within valid ni,nj,nk range.
// Optionally allow an extra index for point addressing
inline void checkIndex
(
const label i,
const label j,
const label k,
const bool isPoint = false
) const;
//- Check that sizes() are valid
inline void checkSizes() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ijkAddressingI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::ijkAddressing::ijkAddressing()
:
sizes_(0, 0, 0)
{}
inline Foam::ijkAddressing::ijkAddressing(const labelVector& ijk)
:
sizes_(ijk)
{
#ifdef FULLDEBUG
checkSizes();
#endif
}
inline Foam::ijkAddressing::ijkAddressing
(
const label ni,
const label nj,
const label nk
)
:
sizes_(ni, nj, nk)
{
#ifdef FULLDEBUG
checkSizes();
#endif
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline const Foam::labelVector& Foam::ijkAddressing::sizes() const
{
return sizes_;
}
inline Foam::labelVector& Foam::ijkAddressing::sizes()
{
return sizes_;
}
inline Foam::label Foam::ijkAddressing::size() const
{
// Could also use cmptProduct(sizes_);
return (sizes_.x() * sizes_.y() * sizes_.z());
}
inline bool Foam::ijkAddressing::empty() const
{
return (!sizes_.x() || !sizes_.y() || !sizes_.z());
}
inline void Foam::ijkAddressing::clear()
{
sizes_ = Zero;
}
inline void Foam::ijkAddressing::reset
(
const label ni,
const label nj,
const label nk
)
{
sizes_.x() = ni;
sizes_.y() = nj;
sizes_.z() = nk;
#ifdef FULLDEBUG
checkSizes();
#endif
}
inline Foam::label Foam::ijkAddressing::index
(
const label i,
const label j,
const label k
) const
{
#ifdef FULLDEBUG
checkIndex(i, j, k);
#endif
return (i + (sizes_.x() * (j + (sizes_.y() * k))));
}
inline void Foam::ijkAddressing::checkIndex
(
const label i,
const label j,
const label k,
const bool isPoint
) const
{
const label extra = (isPoint ? 1 : 0);
if (i < 0 || i >= (sizes_.x() + extra))
{
FatalErrorInFunction
<< "The i-index " << i
<< " is out of range [0," << (sizes_.x() + extra) << ']' << nl
<< abort(FatalError);
}
if (j < 0 || j >= (sizes_.y() + extra))
{
FatalErrorInFunction
<< "The j-index " << j
<< " is out of range [0," << (sizes_.y() + extra) << ']' << nl
<< abort(FatalError);
}
if (k < 0 || k >= (sizes_.z() + extra))
{
FatalErrorInFunction
<< "The k-index " << k
<< " is out of range [0," << (sizes_.z() + extra) << ']' << nl
<< abort(FatalError);
}
}
inline void Foam::ijkAddressing::checkSizes() const
{
if (sizes_.x() < 0)
{
FatalErrorInFunction
<< "The i-size is negative" << nl
<< abort(FatalError);
}
if (sizes_.y() < 0)
{
FatalErrorInFunction
<< "The j-size is negative" << nl
<< abort(FatalError);
}
if (sizes_.z() < 0)
{
FatalErrorInFunction
<< "The k-size is negative" << nl
<< abort(FatalError);
}
}
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::ijkMesh
Description
A simple i-j-k (row-major order) to linear addressing for a
rectilinear mesh. Since the underlying mesh is rectilinear, some
mesh-related sizing information can be derived directly from the
addressing information.
SourceFiles
ijkMeshI.H
\*---------------------------------------------------------------------------*/
#ifndef ijkMesh_H
#define ijkMesh_H
#include "ijkAddressing.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class ijkMesh Declaration
\*---------------------------------------------------------------------------*/
class ijkMesh
:
public ijkAddressing
{
public:
// Constructors
//- Construct zero-sized
inline ijkMesh();
//- Construct with addressing
inline explicit ijkMesh(const labelVector& ijk);
//- Construct with addressing
inline ijkMesh(const label nx, const label ny, const label nz);
// Member Functions
// Access
//- The number of mesh points (nx+1)*(ny+1)*(nz+1) in the i-j-k mesh.
inline label nPoints() const;
//- The number of mesh cells (nx*ny*nz) in the i-j-k mesh
// This is the same as the ijkAddressing::size()
inline label nCells() const;
//- The total number of mesh faces in the i-j-k mesh
inline label nFaces() const;
//- The number of internal faces in the i-j-k mesh
inline label nInternalFaces() const;
//- The number of boundary faces in the i-j-k mesh
inline label nBoundaryFaces() const;
//- The linear cell index for an i-j-k position - same as index()
inline label cellLabel
(
const label i,
const label j,
const label k
) const;
//- The linear point index for an i-j-k position.
// Addressable in the range (ni+1, nj+1, nk+1).
inline label pointLabel
(
const label i,
const label j,
const label k
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "ijkMeshI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::ijkMesh::ijkMesh()
:
ijkAddressing()
{}
inline Foam::ijkMesh::ijkMesh(const labelVector& ijk)
:
ijkAddressing(ijk)
{}
inline Foam::ijkMesh::ijkMesh
(
const label nx,
const label ny,
const label nz
)
:
ijkAddressing(nx, ny, nz)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::label Foam::ijkMesh::nPoints() const
{
if (ijkAddressing::empty())
{
return 0;
}
const labelVector& n = ijkAddressing::sizes();
return ((n.x()+1) * (n.y()+1) * (n.z()+1));
}
inline Foam::label Foam::ijkMesh::nCells() const
{
return ijkAddressing::size();
}
inline Foam::label Foam::ijkMesh::nFaces() const
{
if (ijkAddressing::empty())
{
return 0;
}
const labelVector& n = ijkAddressing::sizes();
return
(
((n.x()+1) * n.y() * n.z())
+ ((n.y()+1) * n.z() * n.x())
+ ((n.z()+1) * n.x() * n.y())
);
}
inline Foam::label Foam::ijkMesh::nInternalFaces() const
{
if (ijkAddressing::empty())
{
return 0;
}
const labelVector& n = ijkAddressing::sizes();
return
(
((n.x()-1) * n.y() * n.z())
+ ((n.y()-1) * n.z() * n.x())
+ ((n.z()-1) * n.x() * n.y())
);
}
inline Foam::label Foam::ijkMesh::nBoundaryFaces() const
{
if (ijkAddressing::empty())
{
return 0;
}
const labelVector& n = ijkAddressing::sizes();
return
(
(2 * n.y() * n.z())
+ (2 * n.z() * n.x())
+ (2 * n.x() * n.y())
);
}
inline Foam::label Foam::ijkMesh::cellLabel
(
const label i,
const label j,
const label k
) const
{
return ijkAddressing::index(i, j, k);
}
inline Foam::label Foam::ijkMesh::pointLabel
(
const label i,
const label j,
const label k
) const
{
#ifdef FULLDEBUG
checkIndex(i, j, k, true);
#endif
const labelVector& n = sizes();
return (i + ((n.x()+1) * (j + (n.y()+1) * k)));
}
// ************************************************************************* //
......@@ -133,16 +133,16 @@ Foam::blockDescriptor::blockDescriptor
const pointField& vertices,
const blockEdgeList& edges,
const blockFaceList& faces,
const Vector<label>& density,
const labelVector& density,
const UList<gradingDescriptors>& expand,
const word& zoneName
)
:
ijkMesh(density),
vertices_(vertices),
blockEdges_(edges),
blockFaces_(faces),
blockShape_(bshape),
density_(density),
expand_(expand),
zoneName_(zoneName),
curvedFaces_(-1),
......@@ -173,10 +173,10 @@ Foam::blockDescriptor::blockDescriptor
Istream& is
)
:
ijkMesh(),
vertices_(vertices),
blockEdges_(edges),
blockFaces_(faces),
density_(0, 0, 0),
expand_(12, gradingDescriptors()),
zoneName_(),
curvedFaces_(-1),
......@@ -212,7 +212,7 @@ Foam::blockDescriptor::blockDescriptor
// New-style: read a list of 3 values
if (t.pToken() == token::BEGIN_LIST)
{
is >> density_;
is >> ijkMesh::sizes();