Added: class ASMu1DLag for unstructured Lagrange 1D patches.

Changed: Moved the Matlab mesh input method to ASMutils.C file.
This commit is contained in:
Knut Morten Okstad
2021-05-28 10:45:29 +02:00
parent e694fa091a
commit cf3261fa12
14 changed files with 503 additions and 168 deletions

View File

@@ -13,7 +13,7 @@
#include "ASM1D.h"
#include "ASMs1DC1.h"
#include "ASMs1DLag.h"
#include "ASMu1DLag.h"
#include "ASMs1DSpec.h"
#include "Vec3Oper.h"
@@ -32,7 +32,10 @@ ASMbase* ASM1D::create (ASM::Discretization discretization,
return new ASMs1DC1(nd,nf);
case ASM::Lagrange:
return new ASMs1DLag(nd,nf);
if (nf > 10) // hack for mesh input from file
return new ASMu1DLag(nd,nf-10,'m');
else
return new ASMs1DLag(nd,nf);
case ASM::Spectral:
return new ASMs1DSpec(nd,nf);

View File

@@ -146,9 +146,10 @@ protected:
int p1; //!< Polynomial order of the basis
private:
const std::vector<Vec3>& coord; //!< Nodal coordinates
const Vec3Vec& coord; //!< Nodal coordinates
std::vector<Vec3> myCoord; //!< The actual nodal coordinates
protected:
Vec3Vec myCoord; //!< The actual nodal coordinates
};
#endif

View File

@@ -174,9 +174,10 @@ protected:
int p2; //!< Polynomial order in second parameter direction
private:
const std::vector<Vec3>& coord; //!< Nodal coordinates
const Vec3Vec& coord; //!< Nodal coordinates
std::vector<Vec3> myCoord; //!< The actual nodal coordinates
protected:
Vec3Vec myCoord; //!< The actual nodal coordinates
};
#endif

View File

@@ -116,7 +116,7 @@ bool ASMsupel::generateFEMTopology ()
int ASMsupel::getNodeSetIdx (const std::string& setName) const
{
int idx = 1;
for (const NodeSet& ns : nodeSets)
for (const ASM::NodeSet& ns : nodeSets)
if (ns.first == setName)
return idx;
else
@@ -129,7 +129,7 @@ int ASMsupel::getNodeSetIdx (const std::string& setName) const
const IntVec& ASMsupel::getNodeSet (int idx) const
{
int count = 0;
for (const NodeSet& ns : nodeSets)
for (const ASM::NodeSet& ns : nodeSets)
if (++count == idx)
return ns.second;
@@ -139,7 +139,7 @@ const IntVec& ASMsupel::getNodeSet (int idx) const
IntVec& ASMsupel::getNodeSet (const std::string& setName)
{
for (NodeSet& ns : nodeSets)
for (ASM::NodeSet& ns : nodeSets)
if (ns.first == setName)
return ns.second;

View File

@@ -15,6 +15,7 @@
#define _ASM_SUPEL_H
#include "ASMbase.h"
#include "ASMutils.h"
#include "ElmMats.h"
#include "Vec3.h"
@@ -112,8 +113,7 @@ private:
Vec3Vec myNodes; //!< Supernode coordinates
ElmMats myElmMat; //!< Duperelement matrices
typedef std::pair<std::string,IntVec> NodeSet; //!< Named node set container
std::vector<NodeSet> nodeSets; //!< Pre-defined node sets for Dirichlet BCs
std::vector<ASM::NodeSet> nodeSets; //!< Node sets for Dirichlet BCs
};
#endif

129
src/ASM/ASMu1DLag.C Normal file
View File

@@ -0,0 +1,129 @@
// $Id$
//==============================================================================
//!
//! \file ASMu1DLag.C
//!
//! \date Aug 26 2021
//!
//! \author Knut Morten Okstad / SINTEF
//!
//! \brief Assembly of unstructured 1D Lagrange FE models.
//!
//==============================================================================
#include "ASMu1DLag.h"
#include "ElementBlock.h"
#include <numeric>
ASMu1DLag::ASMu1DLag (unsigned char n_s,
unsigned char n_f, char fType) : ASMs1DLag(n_s,n_f)
{
fileType = fType;
}
ASMu1DLag::ASMu1DLag (const ASMu1DLag& p, unsigned char n_f) :
ASMs1DLag(p,n_f), nodeSets(p.nodeSets)
{
fileType = 0;
}
ASMu1DLag::ASMu1DLag (const ASMu1DLag& p) :
ASMs1DLag(p), nodeSets(p.nodeSets)
{
fileType = 0;
}
bool ASMu1DLag::read (std::istream& is)
{
switch (fileType) {
case 'm':
case 'M':
return ASM::readMatlab(is,myMNPC,myCoord,nodeSets);
default:
std::cerr <<" *** ASMu1DLag::read: Undefined file format."<< std::endl;
return false;
}
}
bool ASMu1DLag::generateOrientedFEModel (const Vec3& Zaxis)
{
p1 = 2; // So far only linear elements supported
nnod = myCoord.size();
nel = myMNPC.size();
myMLGN.resize(nnod);
myMLGE.resize(nel);
if (nsd == 3 && nf == 6)
{
// This is a 3D beam problem, allocate the nodal/element rotation tensors.
// The nodal rotations are updated during the simulation according to the
// deformation state, whereas the element tensors are kept constant.
myCS.resize(nel,Tensor(3));
myT.resize(nnod,Tensor(3,true)); // Initialize nodal rotations to unity
}
std::iota(myMLGN.begin(),myMLGN.end(),gNod+1);
std::iota(myMLGE.begin(),myMLGE.end(),gEl+1);
gNod += nnod;
gEl += nel;
return myCS.empty() ? true : this->initLocalElementAxes(Zaxis);
}
int ASMu1DLag::getNodeSetIdx (const std::string& setName) const
{
int idx = 1;
for (const ASM::NodeSet& ns : nodeSets)
if (ns.first == setName)
return idx;
else
++idx;
return 0;
}
const IntVec& ASMu1DLag::getNodeSet (int idx) const
{
int count = 0;
for (const ASM::NodeSet& ns : nodeSets)
if (++count == idx)
return ns.second;
return this->ASMbase::getNodeSet(idx);
}
IntVec& ASMu1DLag::getNodeSet (const std::string& setName)
{
for (ASM::NodeSet& ns : nodeSets)
if (ns.first == setName)
return ns.second;
nodeSets.push_back(std::make_pair(setName,IntVec()));
return nodeSets.back().second;
}
bool ASMu1DLag::tesselate (ElementBlock& grid, const int*) const
{
grid.unStructResize(nel,nnod);
size_t i, k;
for (i = 0; i < nnod; i++)
grid.setCoor(i,this->getCoord(1+i));
for (i = k = 0; i < nel; i++)
for (int j : MNPC[i])
grid.setNode(k++,j);
return true;
}

71
src/ASM/ASMu1DLag.h Normal file
View File

@@ -0,0 +1,71 @@
// $Id$
//==============================================================================
//!
//! \file ASMu1DLag.h
//!
//! \date May 26 2021
//!
//! \author Knut Morten Okstad / SINTEF
//!
//! \brief Assembly of unstructured 1D Lagrange FE models.
//!
//==============================================================================
#ifndef _ASM_U1D_LAG_H
#define _ASM_U1D_LAG_H
#include "ASMs1DLag.h"
#include "ASMutils.h"
/*!
\brief Driver for assembly of unstructured 1D Lagrange FE models.
\details This class overrides the methods of its parent class such that
it does not depend on a curve spline object for geometry discretization.
It can therefore be used for any unstructured grid read from mesh files.
*/
class ASMu1DLag : public ASMs1DLag
{
public:
//! \brief Default constructor.
ASMu1DLag(unsigned char n = 1, unsigned char n_f = 1, char fType = 'm');
//! \brief Special copy constructor for sharing of FE data.
ASMu1DLag(const ASMu1DLag& pch, unsigned char n_f);
//! \brief Default copy constructor copying everything.
ASMu1DLag(const ASMu1DLag& pch);
//! \brief Empty destructor.
virtual ~ASMu1DLag() {}
// Methods for model generation
// ============================
//! \brief Creates an instance by reading the given input stream.
virtual bool read(std::istream& is);
//! \brief Generates a beam finite element model for the patch.
//! \param[in] Zaxis Vector defining a point in the local XZ-plane
virtual bool generateOrientedFEModel(const Vec3& Zaxis);
//! \brief Checks if this patch is empty.
virtual bool empty() const { return nel == 0; }
//! \brief Returns (1-based) index of a predefined node set in the patch.
virtual int getNodeSetIdx(const std::string& setName) const;
//! \brief Returns an indexed pre-defined node set.
virtual const IntVec& getNodeSet(int idx) const;
//! \brief Returns a named node set for update.
virtual IntVec& getNodeSet(const std::string& setName);
// Post-processing methods
// =======================
//! \brief Creates a line element model of this patch for visualization.
//! \param[out] grid The generated line grid
//! \note The number of element nodes must be set in \a grid on input.
virtual bool tesselate(ElementBlock& grid, const int*) const;
private:
char fileType; //!< Mesh file format
std::vector<ASM::NodeSet> nodeSets; //!< Node sets for Dirichlet BCs
};
#endif

View File

@@ -13,10 +13,7 @@
#include "ASMu2DLag.h"
#include "ElementBlock.h"
#include "Vec3Oper.h"
#include <numeric>
#include <sstream>
#include <cctype>
ASMu2DLag::ASMu2DLag (unsigned char n_s,
@@ -40,136 +37,12 @@ ASMu2DLag::ASMu2DLag (const ASMu2DLag& p) :
}
/*!
\brief Helper method reading one data line ignoring all whitespace characters.
\param is Input stream to read data from
\param[out] s The read data is placed in this string
\param[in] delim Read until this character is reached
*/
static bool readLine (std::istream& is, std::string& s, char delim = '\n')
{
size_t i, n = 0;
while (n == 0 && std::getline(is,s,delim))
for (i = 0; i < s.length(); i++)
if (!isspace(s[i])) s[n++] = s[i];
s = s.substr(0,n);
for (i = 0; i < n; i++)
if (s[i] == ',') s[i] = ' ';
return n > 0;
}
/*!
This method reads a matlab file with arrays defining a standard FE mesh.
The format corresponds to that of the output method SIMoutput::dumpMatlabGrid.
*/
bool ASMu2DLag::readMatlab (std::istream& is)
{
std::string cline;
if (!readLine(is,cline,'=') ||
cline.find("function") == std::string::npos ||
cline.find("Node") == std::string::npos ||
cline.find("Element") == std::string::npos)
{
std::cerr <<" *** ASMu2DLag::readMatlab: Not a matlab file."<< std::endl;
return false;
}
std::getline(is,cline);
while (readLine(is,cline,'['))
if (cline.find("Node=") == cline.length()-5)
{
while (readLine(is,cline))
{
size_t id; Vec3 X;
std::stringstream(cline) >> id >> X;
#if SP_DEBUG > 1
std::cout << id <<": "<< X << std::endl;
#endif
this->setCoord(id,X);
if (cline.back() == ';') break;
}
#ifdef SP_DEBUG
std::cout <<"Read "<< nnod <<" nodes."<< std::endl;
#endif
}
else if (cline.find("Element=") == cline.length()-8)
{
while (readLine(is,cline))
{
size_t id; int node;
IntVec mnpc; mnpc.reserve(4);
std::istringstream selem(cline);
selem >> id >> node;
while (selem)
{
mnpc.push_back(node-1);
selem >> node;
}
#if SP_DEBUG > 1
std::cout << id <<":";
for (int n : mnpc) std::cout <<" "<< n;
std::cout << std::endl;
#endif
if (mnpc.size() == 4)
std::swap(mnpc[2],mnpc[3]);
else
{
std::cerr <<" ** ASMu2DLag::readMatlab: "<< mnpc.size()
<<"-noded elements not supported (ignored).\n";
continue;
}
if (id > myMNPC.size()) myMNPC.resize(id);
myMNPC[id-1] = mnpc;
if (cline.back() == ';') break;
}
nel = myMNPC.size();
#ifdef SP_DEBUG
std::cout <<"Read "<< nel <<" elements."<< std::endl;
#endif
}
else if (cline.back() == '=')
{
std::string setname = cline.substr(0,cline.length()-1);
if (readLine(is,cline,']'))
{
size_t i = 0; // Remove the '...' continuation markers
while ((i = cline.find_first_of('.',i)) != std::string::npos)
cline.erase(i,1);
int node;
IntVec nodes;
std::istringstream selem(cline);
selem >> node;
while (selem)
{
nodes.push_back(node);
selem >> node;
}
#if SP_DEBUG > 1
std::cout <<"Node set \""<< setname <<"\":";
for (int n : nodes) std::cout <<" "<< n;
std::cout << std::endl;
#endif
std::getline(is,cline);
nodeSets.push_back(std::make_pair(setname,nodes));
}
}
return true;
}
bool ASMu2DLag::read (std::istream& is)
{
switch (fileType) {
case 'm':
case 'M':
return this->readMatlab(is);
return ASM::readMatlab(is,myMNPC,myCoord,nodeSets);
default:
std::cerr <<" *** ASMu2DLag::read: Undefined file format."<< std::endl;
return false;
@@ -181,6 +54,9 @@ bool ASMu2DLag::generateFEMTopology ()
{
p1 = p2 = 2; // So far only linear elements supported
nnod = myCoord.size();
nel = myMNPC.size();
myMLGN.resize(nnod);
myMLGE.resize(nel);
@@ -197,8 +73,8 @@ bool ASMu2DLag::generateFEMTopology ()
int ASMu2DLag::getNodeSetIdx (const std::string& setName) const
{
int idx = 1;
for (const auto& it : nodeSets)
if (it.first == setName)
for (const ASM::NodeSet& ns : nodeSets)
if (ns.first == setName)
return idx;
else
++idx;
@@ -210,9 +86,9 @@ int ASMu2DLag::getNodeSetIdx (const std::string& setName) const
const IntVec& ASMu2DLag::getNodeSet (int idx) const
{
int count = 0;
for (const auto& it : nodeSets)
for (const ASM::NodeSet& ns : nodeSets)
if (++count == idx)
return it.second;
return ns.second;
return this->ASMbase::getNodeSet(idx);
}
@@ -220,9 +96,9 @@ const IntVec& ASMu2DLag::getNodeSet (int idx) const
IntVec& ASMu2DLag::getNodeSet (const std::string& setName)
{
for (NodeSet& it : nodeSets)
if (it.first == setName)
return it.second;
for (ASM::NodeSet& ns : nodeSets)
if (ns.first == setName)
return ns.second;
nodeSets.push_back(std::make_pair(setName,IntVec()));
return nodeSets.back().second;

View File

@@ -11,10 +11,11 @@
//!
//==============================================================================
#ifndef _ASM_S2D_MATLAB_H
#define _ASM_S2D_MATLAB_H
#ifndef _ASM_U2D_LAG_H
#define _ASM_U2D_LAG_H
#include "ASMs2DLag.h"
#include "ASMutils.h"
/*!
@@ -30,7 +31,7 @@ public:
//! \brief Default constructor.
ASMu2DLag(unsigned char n = 2, unsigned char n_f = 2, char fType = 'm');
//! \brief Special copy constructor for sharing of FE data.
ASMu2DLag(const ASMu2DLag& pch, unsigned char nf);
ASMu2DLag(const ASMu2DLag& pch, unsigned char n_f);
//! \brief Default copy constructor copying everything.
ASMu2DLag(const ASMu2DLag& pch);
//! \brief Empty destructor.
@@ -39,11 +40,6 @@ public:
// Methods for model generation
// ============================
private:
//! \brief Creates an instance by reading Matlab commands from a stream.
bool readMatlab(std::istream& is);
public:
//! \brief Creates an instance by reading the given input stream.
virtual bool read(std::istream& is);
//! \brief Generates the finite element topology data for the patch.
@@ -71,9 +67,8 @@ public:
virtual bool tesselate(ElementBlock& grid, const int*) const;
private:
char fileType; //!< Mesh file format
typedef std::pair<std::string,IntVec> NodeSet; //!< Named node set container
std::vector<NodeSet> nodeSets; //!< Pre-defined node sets for Dirichlet BCs
char fileType; //!< Mesh file format
std::vector<ASM::NodeSet> nodeSets; //!< Node sets for Dirichlet BCs
};
#endif

137
src/ASM/ASMutils.C Normal file
View File

@@ -0,0 +1,137 @@
// $Id$
//==============================================================================
//!
//! \file ASMutils.C
//!
//! \date Aug 12 2017
//!
//! \author Knut Morten Okstad / SINTEF
//!
//! \brief Various utilities for assembly scope.
//!
//==============================================================================
#include "ASMutils.h"
#include "Vec3Oper.h"
#include "Vec3.h"
#include <sstream>
#include <cctype>
/*!
This function reads a matlab file with arrays defining a standard FE mesh.
The format corresponds to that of the output method SIMoutput::dumpMatlabGrid.
*/
bool ASM::readMatlab (std::istream& is, IntMat& MNPC, std::vector<Vec3>& nodes,
std::vector<NodeSet>& nodeSets)
{
// Lambda function reading one data line ignoring all whitespace characters.
auto&& readLine = [&is](std::string& s, char delim = '\n')
{
size_t i, n = 0;
while (n == 0 && std::getline(is,s,delim))
for (i = 0; i < s.length(); i++)
if (!isspace(s[i])) s[n++] = s[i];
s = s.substr(0,n);
for (i = 0; i < n; i++)
if (s[i] == ',') s[i] = ' ';
return n > 0;
};
std::string cline;
if (!readLine(cline,'=') ||
cline.find("function") == std::string::npos ||
cline.find("Node") == std::string::npos ||
cline.find("Element") == std::string::npos)
{
std::cerr <<" *** ASM::readMatlab: Not a matlab file."<< std::endl;
return false;
}
std::getline(is,cline);
while (readLine(cline,'['))
if (cline.find("Node=") == cline.length()-5)
{
while (readLine(cline))
{
size_t id; Vec3 X;
std::istringstream(cline) >> id >> X;
#if SP_DEBUG > 1
std::cout << id <<": "<< X << std::endl;
#endif
if (id > nodes.size()) nodes.resize(id);
nodes[id-1] = X;
if (cline.back() == ';') break;
}
#ifdef SP_DEBUG
std::cout <<"Read "<< nodes.size() <<" nodes."<< std::endl;
#endif
}
else if (cline.find("Element=") == cline.length()-8)
{
while (readLine(cline))
{
size_t id; int node;
IntVec mnpc; mnpc.reserve(4);
std::istringstream selem(cline);
selem >> id >> node;
while (selem)
{
mnpc.push_back(node-1);
selem >> node;
}
#if SP_DEBUG > 1
std::cout << id <<":";
for (int n : mnpc) std::cout <<" "<< n;
std::cout << std::endl;
#endif
if (mnpc.size() == 4)
std::swap(mnpc[2],mnpc[3]);
else if (mnpc.size() != 2)
{
std::cerr <<" ** ASM::readMatlab: "<< mnpc.size()
<<"-noded elements not supported (ignored).\n";
continue;
}
if (id > MNPC.size()) MNPC.resize(id);
MNPC[id-1] = mnpc;
if (cline.back() == ';') break;
}
#ifdef SP_DEBUG
std::cout <<"Read "<< MNPC.size() <<" elements."<< std::endl;
#endif
}
else if (cline.back() == '=')
{
std::string setname = cline.substr(0,cline.length()-1);
if (readLine(cline,']'))
{
size_t i = 0; // Remove the '...' continuation markers
while ((i = cline.find_first_of('.',i)) != std::string::npos)
cline.erase(i,1);
int node;
IntVec nodes;
std::istringstream selem(cline);
selem >> node;
while (selem)
{
nodes.push_back(node);
selem >> node;
}
#if SP_DEBUG > 1
std::cout <<"Node set \""<< setname <<"\":";
for (int n : nodes) std::cout <<" "<< n;
std::cout << std::endl;
#endif
std::getline(is,cline);
nodeSets.push_back(std::make_pair(setname,nodes));
}
}
return true;
}

36
src/ASM/ASMutils.h Normal file
View File

@@ -0,0 +1,36 @@
// $Id$
//==============================================================================
//!
//! \file ASMutils.h
//!
//! \date Aug 12 2017
//!
//! \author Knut Morten Okstad / SINTEF
//!
//! \brief Various utilities for assembly scope.
//!
//==============================================================================
#ifndef _ASM_UTILS_H
#define _ASM_UTILS_H
#include <iostream>
#include <vector>
#include <string>
class Vec3;
typedef std::vector<int> IntVec; //!< General integer vector
typedef std::vector<IntVec> IntMat; //!< General 2D integer matrix
namespace ASM
{
typedef std::pair<std::string,IntVec> NodeSet; //!< Named node set container
//! \brief Creates a mesh by reading Matlab commands from an input stream.
bool readMatlab(std::istream& is, IntMat& MNPC, std::vector<Vec3>& nodes,
std::vector<NodeSet>& nodeSets);
};
#endif

View File

@@ -10,7 +10,9 @@
//!
//==============================================================================
#include "SIM1D.h"
#include "SIM2D.h"
#include "ASMs1D.h"
#include "ASMs2D.h"
#include "ModelGenerator.h"
#include "tinyxml.h"
@@ -19,6 +21,27 @@
#include "gtest/gtest.h"
class SIM1D_default : public SIM1D
{
public:
SIM1D_default(int nu)
{
// Create a unit grid with (nu+1) linear elements
this->createDefaultModel();
ASMs1D* pch1 = static_cast<ASMs1D*>(myModel.front());
EXPECT_TRUE(pch1->uniformRefine(nu));
EXPECT_TRUE(this->createFEMmodel());
// Create topological boundary entities (vertices)
TiXmlDocument doc;
doc.Parse("<geometry sets='true'/>",nullptr,TIXML_ENCODING_UTF8);
DefaultGeometry1D(doc.RootElement()).createTopologySets(*this);
EXPECT_EQ(myEntitys.size(),4U);
}
virtual ~SIM1D_default() {}
};
class SIM2D_default : public SIM2D
{
public:
@@ -41,6 +64,23 @@ public:
};
class SIM1D_matlab : public SIM1D
{
public:
SIM1D_matlab(const char* inputFile)
{
std::string xml("<geometry><patchfile type='matlab'>");
xml.append(inputFile);
xml.append("</patchfile></geometry>");
// Read the FE model from the provided Matlab file
EXPECT_TRUE(this->loadXML(xml.c_str()));
EXPECT_TRUE(this->createFEMmodel());
}
virtual ~SIM1D_matlab() {}
};
class SIM2D_matlab : public SIM2D
{
public:
@@ -48,7 +88,7 @@ public:
{
std::string xml("<geometry><patchfile type='matlab'>");
xml.append(inputFile);
xml.append("</geometry>");
xml.append("</patchfile></geometry>");
// Read the FE model from the provided Matlab file
EXPECT_TRUE(this->loadXML(xml.c_str()));
@@ -62,12 +102,12 @@ TEST(TestMatlabPatch, IO)
{
// Create a 5x4 element mesh and write it to a matlab file
SIM2D_default sim1(4,3);
std::ofstream out("/tmp/testGrid.m");
std::ofstream out("/tmp/testGrid2.m");
ASSERT_TRUE(sim1.dumpMatlabGrid(out,"TheMesh",{"Boundary","Edge2"}));
out.close();
// Read the matlab file into a new SIM and compare the models
SIM2D_matlab sim2("/tmp/testGrid.m");
SIM2D_matlab sim2("/tmp/testGrid2.m");
EXPECT_EQ(sim1.getNoNodes(),sim2.getNoNodes());
EXPECT_EQ(sim1.getNoElms(),sim2.getNoElms());
ASMbase* pch1 = sim1.getPatch(1);
@@ -96,4 +136,36 @@ TEST(TestMatlabPatch, IO)
IntVec corner = pch2->getNodeSet(idx3);
ASSERT_EQ(corner.size(),1U);
EXPECT_EQ(corner.front(),1);
// Create a 6-element 1D mesh and write it to a matlab file
SIM1D_default sim3(5);
out.open("/tmp/testGrid1.m");
ASSERT_TRUE(sim3.dumpMatlabGrid(out,"TheMesh",{"Boundary","Vertex2"}));
out.close();
// Read the matlab file into a new SIM and compare the models
SIM1D_matlab sim4("/tmp/testGrid1.m");
EXPECT_EQ(sim3.getNoNodes(),sim3.getNoNodes());
EXPECT_EQ(sim3.getNoElms(),sim3.getNoElms());
pch1 = sim3.getPatch(1);
pch2 = sim4.getPatch(1);
ASSERT_TRUE(pch1 != nullptr);
ASSERT_TRUE(pch2 != nullptr);
idx1 = pch2->getNodeSetIdx("Boundary");
idx2 = pch2->getNodeSetIdx("Vertex2");
EXPECT_EQ(idx1,1);
EXPECT_EQ(idx2,2);
b1.clear();
b2 = pch2->getNodeSet(idx1);
for (int vert = 1; vert <= 2; vert++)
pch1->getBoundaryNodes(vert,b1);
b1set.clear();
for (int n : b1) b1set.insert(n);
EXPECT_EQ(b1set.size(),b2.size());
EXPECT_TRUE(IntVec(b1set.begin(),b1set.end()) == b2);
IntVec v1, v2 = pch2->getNodeSet(idx2);
pch1->getBoundaryNodes(2,v1);
EXPECT_EQ(v1.size(),v2.size());
EXPECT_TRUE(v1 == v2);
}

View File

@@ -250,11 +250,31 @@ bool SIM1D::parseBCTag (const TiXmlElement* elem)
bool SIM1D::parse (const TiXmlElement* elem)
{
// Check if the number of dimensions is specified
int idim = nsd;
if (!strcasecmp(elem->Value(),"geometry"))
{
// Check for unstructured Lagrange mesh.
// This code must be placed here (and not in parseGeometryTag)
// due to instantiation of the ASMu1DLag class.
const TiXmlElement* child = elem->FirstChildElement();
for (; child && nf < 10; child = child->NextSiblingElement())
if (!strcasecmp(child->Value(),"patchfile"))
{
std::string type;
if (utl::getAttribute(child,"type",type,true))
{
if (type == "matlab")
nf += 10;
else
continue;
opt.discretization = ASM::Lagrange;
}
}
// Check if the number of dimensions is specified
int idim = nsd;
if (utl::getAttribute(elem,"dim",idim))
nsd = idim;
}
bool result = this->SIMgeneric::parse(elem);

View File

@@ -1316,12 +1316,6 @@ bool SIMoutput::dumpMatlabGrid (std::ostream& os, const std::string& name,
const std::vector<std::string>& sets,
double scale) const
{
if (this->getNoParamDim() != 2)
{
std::cerr <<" *** SIMoutput::dumpMatlabGrid: For 2D only."<< std::endl;
return false;
}
// Write function definition
os <<"function [Node, Element";
for (const std::string& setname : sets) os <<", "<< setname;