Commit 800e89e7 authored by Dave Moxey's avatar Dave Moxey
Browse files

Merge remote-tracking branch 'upstream/master' into feature/hdf5

parents 7ba7e9f1 168847e7
......@@ -10,9 +10,14 @@ v4.3.1
- Fix Homogeneous transform when unshuffling is not used. (!599)
- Fix namespace pollution in library header files. (!601)
- Fix issue with METIS compilation on clang 7.3 (!603)
- Fix issue with heterogeneous quadrilaterals (!607)
- Fix bug in modified Arnoldi algorithm causing convergence to be reported when
number of vectors is less than `nvec` (!608)
- Fix uninitialised array bug in AssemblyMap (!598)
- Fix issue with LAPACK call in eigenvalue calculation (!610)
- Fix FieldConvert processing of partitions in serial (!612)
- Fix use of multi-level static condensation in parallel with periodic
boundary conditions (!614)
**NekMesh**:
- Fix incorrect link directory on CCMIO library.
......@@ -21,6 +26,10 @@ v4.3.1
- Fix to FLD input to update the field definitions always, not just when a range
is specified. (!611)
**Tester**:
- Remove requirement for executable to be specified in .tst file if it is
overridden on the command-line (!595)
v4.3.0
------
**Library:**
......
......@@ -29,8 +29,8 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
//
// Description: Matrix functions that depend on storage policy. Putting
// methods in these separate classes makes it easier to use them from
// Description: Matrix functions that depend on storage policy. Putting
// methods in these separate classes makes it easier to use them from
// normal, scaled, and block matrices.
//
///////////////////////////////////////////////////////////////////////////////
......@@ -48,40 +48,40 @@
namespace Nektar
{
struct LIB_UTILITIES_EXPORT BandedMatrixFuncs
{
{
/// \brief Calculates and returns the storage size required.
///
/// This method assumes that the matrix will be used with LU factorizationa and
/// This method assumes that the matrix will be used with LU factorizationa and
/// allocates additional storage as appropriate.
static unsigned int GetRequiredStorageSize(unsigned int totalRows, unsigned int totalColumns,
unsigned int subDiags, unsigned int superDiags);
static unsigned int CalculateNumberOfDiags(unsigned int totalRows, unsigned int diags);
static unsigned int CalculateNumberOfRows(unsigned int totalRows, unsigned int subDiags, unsigned int superDiags);
static unsigned int CalculateIndex(unsigned int totalRows,
static unsigned int CalculateIndex(unsigned int totalRows,
unsigned int totalColumns,
unsigned int row, unsigned int column,
unsigned int sub, unsigned int super);
static boost::tuples::tuple<unsigned int, unsigned int>
static boost::tuples::tuple<unsigned int, unsigned int>
Advance(const unsigned int totalRows, const unsigned int totalColumns,
const unsigned int curRow, const unsigned int curColumn);
};
struct LIB_UTILITIES_EXPORT FullMatrixFuncs
{
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns);
static unsigned int CalculateIndex(unsigned int totalRows, unsigned int totalColumns, unsigned int curRow, unsigned int curColumn);
static boost::tuples::tuple<unsigned int, unsigned int>
static boost::tuples::tuple<unsigned int, unsigned int>
Advance(const unsigned int totalRows, const unsigned int totalColumns,
const unsigned int curRow, const unsigned int curColumn);
template<typename DataType>
static void Invert(unsigned int rows, unsigned int columns,
Array<OneD, DataType>& data,
......@@ -96,9 +96,9 @@ namespace Nektar
int info = 0;
Array<OneD, int> ipivot(n);
Array<OneD, DataType> work(n);
Lapack::Dgetrf(m, n, data.get(), m, ipivot.get(), info);
if( info < 0 )
{
std::string message = "ERROR: The " + boost::lexical_cast<std::string>(-info) + "th parameter had an illegal parameter for dgetrf";
......@@ -108,11 +108,11 @@ namespace Nektar
{
std::string message = "ERROR: Element u_" + boost::lexical_cast<std::string>(info) + boost::lexical_cast<std::string>(info) + " is 0 from dgetrf";
ASSERTL0(false, message.c_str());
}
}
Lapack::Dgetri(n, data.get(), n, ipivot.get(),
work.get(), n, info);
if( info < 0 )
{
std::string message = "ERROR: The " + boost::lexical_cast<std::string>(-info) + "th parameter had an illegal parameter for dgetri";
......@@ -122,8 +122,8 @@ namespace Nektar
{
std::string message = "ERROR: Element u_" + boost::lexical_cast<std::string>(info) + boost::lexical_cast<std::string>(info) + " is 0 from dgetri";
ASSERTL0(false, message.c_str());
}
}
#else
// error Full matrix inversion not supported without blas.
BOOST_STATIC_ASSERT(sizeof(DataType) == 0);
......@@ -132,18 +132,18 @@ namespace Nektar
static void EigenSolve(unsigned int n,
const Array<OneD, const double>& A,
Array<OneD, NekDouble> &EigValReal,
Array<OneD, NekDouble> &EigValImag,
Array<OneD, NekDouble> &EigValReal,
Array<OneD, NekDouble> &EigValImag,
Array<OneD, NekDouble> &EigVecs = NullNekDouble1DArray)
{
int lda = n,info = 0;
NekDouble dum;
int lwork = 3*lda;
Array<OneD,NekDouble> work(3*lda);
char uplo = 'N';
if(EigVecs != NullNekDouble1DArray) // calculate Right Eigen Vectors
{
int lwork = 4*lda;
Array<OneD,NekDouble> work(4*lda);
char lrev = 'V';
Lapack::Dgeev(uplo,lrev,lda, A.get(),lda,
EigValReal.get(),
......@@ -154,8 +154,10 @@ namespace Nektar
}
else
{
int lwork = 3*lda;
Array<OneD,NekDouble> work(3*lda);
char lrev = 'N';
Lapack::Dgeev(uplo,lrev,lda,
Lapack::Dgeev(uplo,lrev,lda,
A.get(),lda,
EigValReal.get(),
EigValImag.get(),
......@@ -163,7 +165,7 @@ namespace Nektar
&work[0],lwork,info);
}
ASSERTL0(info == 0,"Info is not zero");
}
};
......@@ -171,22 +173,22 @@ namespace Nektar
{
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns);
};
struct LIB_UTILITIES_EXPORT UpperTriangularMatrixFuncs : public TriangularMatrixFuncs
{
static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn);
static boost::tuples::tuple<unsigned int, unsigned int>
static boost::tuples::tuple<unsigned int, unsigned int>
Advance(const unsigned int totalRows, const unsigned int totalColumns,
const unsigned int curRow, const unsigned int curColumn);
};
struct LIB_UTILITIES_EXPORT LowerTriangularMatrixFuncs : public TriangularMatrixFuncs
{
{
static unsigned int CalculateIndex(unsigned int totalColumns, unsigned int curRow, unsigned int curColumn);
static boost::tuples::tuple<unsigned int, unsigned int>
static boost::tuples::tuple<unsigned int, unsigned int>
Advance(const unsigned int totalRows, const unsigned int totalColumns,
const unsigned int curRow, const unsigned int curColumn,
char transpose = 'N');
......@@ -197,17 +199,17 @@ namespace Nektar
struct LIB_UTILITIES_EXPORT SymmetricMatrixFuncs : private TriangularMatrixFuncs
{
using TriangularMatrixFuncs::GetRequiredStorageSize;
static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn);
static boost::tuples::tuple<unsigned int, unsigned int>
static boost::tuples::tuple<unsigned int, unsigned int>
Advance(const unsigned int totalRows, const unsigned int totalColumns,
const unsigned int curRow, const unsigned int curColumn);
};
struct LIB_UTILITIES_EXPORT DiagonalMatrixFuncs
{
static boost::tuples::tuple<unsigned int, unsigned int>
static boost::tuples::tuple<unsigned int, unsigned int>
Advance(const unsigned int totalRows, const unsigned int totalColumns,
const unsigned int curRow, const unsigned int curColumn);
......@@ -221,9 +223,9 @@ namespace Nektar
data[i] = 1.0/data[i];
}
}
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns);
static unsigned int CalculateIndex(unsigned int row, unsigned int col);
};
......@@ -233,13 +235,13 @@ namespace Nektar
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns,
unsigned int nSubSuperDiags);
};
struct LIB_UTILITIES_EXPORT UpperTriangularBandedMatrixFuncs : public TriangularBandedMatrixFuncs
{
};
struct LIB_UTILITIES_EXPORT LowerTriangularBandedMatrixFuncs : public TriangularBandedMatrixFuncs
{
{
};
/// \internal
......@@ -247,8 +249,8 @@ namespace Nektar
struct LIB_UTILITIES_EXPORT SymmetricBandedMatrixFuncs : private TriangularBandedMatrixFuncs
{
using TriangularBandedMatrixFuncs::GetRequiredStorageSize;
static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn,
static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn,
unsigned int nSuperDiags);
};
......
......@@ -899,7 +899,7 @@ namespace Nektar
outarray = Array<OneD, int>(nquad1);
for (int i = 0; i < nquad1; ++i)
{
outarray[i] = (nquad0-1) + i*nquad1;
outarray[i] = (nquad0-1) + i*nquad0;
}
break;
case 2:
......@@ -980,7 +980,7 @@ namespace Nektar
&(jac[0])+(nquad0-1), nquad0,
&(j[0]), 1);
for (i = 0; i < nquad0; ++i)
for (i = 0; i < nquad1; ++i)
{
outarray[i] = j[i]*sqrt(g0[i]*g0[i] +
g2[i]*g2[i]);
......@@ -1020,7 +1020,7 @@ namespace Nektar
&(jac[0])+nquad0*(nquad1-1), -nquad0,
&(j[0]), 1);
for (i = 0; i < nquad0; ++i)
for (i = 0; i < nquad1; ++i)
{
outarray[i] = j[i]*sqrt(g0[i]*g0[i] +
g2[i]*g2[i]);
......@@ -1195,7 +1195,15 @@ namespace Nektar
LibUtilities::PointsKeyVector ptsKeys = GetPointsKeys();
const Array<TwoD, const NekDouble> & df = geomFactors->GetDerivFactors(ptsKeys);
const Array<OneD, const NekDouble> & jac = geomFactors->GetJac(ptsKeys);
int nqe = m_base[0]->GetNumPoints();
int nqe;
if (edge == 0 || edge == 2)
{
nqe = m_base[0]->GetNumPoints();
}
else
{
nqe = m_base[1]->GetNumPoints();
}
int vCoordDim = GetCoordim();
m_edgeNormals[edge] = Array<OneD, Array<OneD, NekDouble> >
......
......@@ -504,7 +504,7 @@ namespace Nektar
{
if (pIt->second[i].isLocal)
{
graph[0][pIt->second[i].id] = gId;
graph[0][pIt->second[i].id] = graph[0][meshVertId];
}
}
}
......@@ -528,7 +528,7 @@ namespace Nektar
{
if (pIt->second[i].isLocal)
{
graph[0][pIt->second[i].id] = gId;
graph[0][pIt->second[i].id] = graph[0][pIt->first];
}
}
}
......@@ -692,6 +692,7 @@ namespace Nektar
if (i == pIt->second.size())
{
boost::add_vertex(boostGraphObj);
tempGraph[0][meshVertId] = tempGraphVertId++;
m_numNonDirVertexModes++;
}
......@@ -807,6 +808,7 @@ namespace Nektar
if (i == pIt->second.size())
{
boost::add_vertex(boostGraphObj);
tempGraph[1][meshEdgeId] = tempGraphVertId++;
m_numNonDirEdgeModes += EdgeSize[meshEdgeId];
m_numNonDirEdges++;
......@@ -857,6 +859,7 @@ namespace Nektar
meshFaceId = pIt->first;
ASSERTL0(graph[2].count(meshFaceId) == 0,
"This periodic boundary edge has been specified before");
boost::add_vertex(boostGraphObj);
tempGraph[2][meshFaceId] = tempGraphVertId++;
nFaceIntCoeffs = FaceSize[meshFaceId];
m_numNonDirFaceModes+=nFaceIntCoeffs;
......@@ -869,6 +872,7 @@ namespace Nektar
ASSERTL0(graph[2].count(pIt->second[0].id) == 0,
"This periodic boundary face has been specified before");
boost::add_vertex(boostGraphObj);
tempGraph[2][pIt->first] = tempGraphVertId;
tempGraph[2][pIt->second[0].id] = tempGraphVertId++;
nFaceIntCoeffs = FaceSize[pIt->first];
......@@ -1052,7 +1056,7 @@ namespace Nektar
}
// Container to store vertices of the graph which correspond to
// degrees of freedom along the boundary.
// degrees of freedom along the boundary and periodic BCs.
set<int> partVerts;
if (m_solnType == eIterativeMultiLevelStaticCond ||
......@@ -1167,6 +1171,29 @@ namespace Nektar
}
}
}
// Now fill with all vertices on periodic BCs
for (pIt = periodicVerts.begin(); pIt != periodicVerts.end(); ++pIt)
{
if (graph[0].count(pIt->first) == 0)
{
partVerts.insert(tempGraph[0][pIt->first]);
}
}
for (pIt = periodicEdges.begin(); pIt != periodicEdges.end(); ++pIt)
{
if (graph[1].count(pIt->first) == 0)
{
partVerts.insert(tempGraph[1][pIt->first]);
}
}
for (pIt = periodicFaces.begin(); pIt != periodicFaces.end(); ++pIt)
{
if (graph[2].count(pIt->first) == 0)
{
partVerts.insert(tempGraph[2][pIt->first]);
}
}
}
int nGraphVerts = tempGraphVertId;
......
......@@ -150,7 +150,7 @@ namespace Nektar
indx = data[i].id;
/// See if this face has curves.
it = m_curvedFaces.find(indx);
it = m_curvedEdges.find(indx);
PointGeomSharedPtr vertices[2] = {
GetVertex(data[i].v0), GetVertex(data[i].v1)};
......
......@@ -119,6 +119,7 @@ IF( NEKTAR_SOLVER_INCNAVIERSTOKES )
ADD_NEKTAR_TEST_LENGTHY(Hex_channel_m8_par)
ADD_NEKTAR_TEST_LENGTHY(Pyr_channel_m6_par)
ADD_NEKTAR_TEST_LENGTHY(Hex_channel_m8_srhs_par)
ADD_NEKTAR_TEST(Tet_channel_m4_per_xxt_ml_par)
ADD_NEKTAR_TEST(Tet_channel_m8_par)
ADD_NEKTAR_TEST_LENGTHY(Tet_channel_m8_iter_ml_par)
ADD_NEKTAR_TEST_LENGTHY(bfs_tg_par)
......
......@@ -2,7 +2,7 @@
<test>
<description>3D channel flow, Tetrahedral elements, P=4, periodic BCs</description>
<executable>IncNavierStokesSolver</executable>
<parameters>Tet_channel_m4_per.xml</parameters>
<parameters>-I GlobalSysSoln=DirectStaticCond Tet_channel_m4_per.xml</parameters>
<files>
<file description="Session File">Tet_channel_m4_per.xml</file>
</files>
......
......@@ -84,7 +84,6 @@
<I PROPERTY="AdvectionForm" VALUE="Convective" />
<I PROPERTY="Projection" VALUE="Galerkin" />
<I PROPERTY="TimeIntegrationMethod" VALUE="IMEXOrder1" />
<I PROPERTY="GlobalSysSoln" VALUE="DirectStaticCond" />
</SOLVERINFO>
<PARAMETERS>
......
<?xml version="1.0" encoding="utf-8" ?>
<test>
<description>3D channel flow, Tetrahedral elements, P=4, periodic BCs, XxtMultiLevelStaticCond, par(2)</description>
<executable>IncNavierStokesSolver</executable>
<parameters>--use-metis -I GlobalSysSoln=XxtMultiLevelStaticCond Tet_channel_m4_per.xml</parameters>
<processes>2</processes>
<files>
<file description="Session File">Tet_channel_m4_per.xml</file>
</files>
<metrics>
<metric type="L2" id="1">
<value variable="u" tolerance="1e-12">0</value>
<value variable="v" tolerance="1e-12">0</value>
<value variable="w" tolerance="1e-12">0</value>
<value variable="p" tolerance="1e-12">0</value>
</metric>
<metric type="Linf" id="2">
<value variable="u" tolerance="1e-12">0</value>
<value variable="v" tolerance="1e-12">0</value>
<value variable="w" tolerance="1e-12">0</value>
<value variable="p" tolerance="1e-12">0</value>
</metric>
</metrics>
</test>
......@@ -44,7 +44,8 @@ using namespace std;
namespace Nektar
{
TestData::TestData(const fs::path& pFilename)
TestData::TestData(const fs::path& pFilename, po::variables_map& pVm)
: m_cmdoptions(pVm)
{
// Process test file format.
#if BOOST_VERSION > 104200
......@@ -71,15 +72,9 @@ namespace Nektar
return m_description;
}
const std::string TestData::GetExecutable() const
const fs::path& TestData::GetExecutable() const
{
std::string execname = m_executable;
#if defined(RELWITHDEBINFO)
execname += "-rg";
#elif !defined(NDEBUG)
execname += "-g";
#endif
return execname;
return m_executable;
}
const std::string& TestData::GetParameters() const
......@@ -145,10 +140,23 @@ namespace Nektar
ASSERTL0(tmp, "Cannot find 'description' for test.");
m_description = string(tmp->GetText());
// Find executable tag.
tmp = testElement->FirstChildElement("executable");
ASSERTL0(tmp, "Cannot find 'executable' for test.");
m_executable = string(tmp->GetText());
// Find executable.
if (m_cmdoptions.count("executable"))
{
m_executable = fs::path(
m_cmdoptions["executable"].as<std::string>());
}
else
{
tmp = testElement->FirstChildElement("executable");
ASSERTL0(tmp, "Cannot find 'executable' for test.");
m_executable = fs::path(tmp->GetText());
#if defined(RELWITHDEBINFO)
m_executable += "-rg";
#elif !defined(NDEBUG)
m_executable += "-g";
#endif
}
// Find parameters tag.
tmp = testElement->FirstChildElement("parameters");
......
......@@ -36,6 +36,7 @@
#ifndef NEKTAR_TESTER_TESTDATA
#define NEKTAR_TESTER_TESTDATA
#include <boost/program_options.hpp>
#include <boost/filesystem.hpp>
#include <string>
......@@ -44,6 +45,7 @@
#include <tinyxml.h>
namespace fs = boost::filesystem;
namespace po = boost::program_options;
namespace Nektar
{
......@@ -56,11 +58,11 @@ namespace Nektar
class TestData
{
public:
TestData(const fs::path& pFilename);
TestData(const fs::path& pFilename, po::variables_map& pVm);
TestData(const TestData& pSrc);
const std::string& GetDescription() const;
const std::string GetExecutable() const;
const fs::path& GetExecutable() const;
const std::string& GetParameters() const;
const unsigned int& GetNProcesses() const;
......@@ -75,9 +77,9 @@ namespace Nektar
void SaveFile();
private:
std::string m_filename;
po::variables_map m_cmdoptions;
std::string m_description;
std::string m_executable;
fs::path m_executable;
std::string m_parameters;
unsigned int m_processes;
TiXmlDocument* m_doc;
......
......@@ -148,7 +148,7 @@ int main(int argc, char *argv[])
try
{
// Parse the test file
TestData file(specFile);
TestData file(specFile, vm);
// Generate the metric objects
vector<MetricSharedPtr> metrics;
......@@ -220,22 +220,12 @@ int main(int argc, char *argv[])
+ " ";
}
fs::path execPath;
if (vm.count("executable"))
fs::path execPath = startDir / file.GetExecutable();
if (!fs::exists(execPath))
{
execPath = vm["executable"].as<std::string>();
execPath = file.GetExecutable();
}
else
{
// If executable doesn't exist in path then hope that it is in the
// user's PATH environment variable.
execPath = startDir / fs::path(file.GetExecutable());
if (!fs::exists(execPath))
{
execPath = fs::path(file.GetExecutable());
}
}
command += PortablePath(execPath);
command += " ";
command += file.GetParameters();
......
......@@ -211,6 +211,9 @@ int main(int argc, char* argv[])
f->m_comm = boost::shared_ptr<FieldConvertComm>(
new FieldConvertComm(argc, argv, nprocs,rank));
// Set forceoutput option. Otherwise only procid 0 will write file
vm.insert(std::make_pair("forceoutput", po::variable_value()));
}
else
{
......
......@@ -122,7 +122,7 @@ void OutputInfo::Process(po::variables_map &vm)
LibUtilities::GetMeshPartitionFactory().CreateInstance(
vPartitionerName, vSession);
vMeshPartition->PartitionMesh(false);
vMeshPartition->PartitionMesh(nprocs, true);
// get hold of local partition ids
std::vector<std::vector<unsigned int> > ElementIDs(nprocs);
......