You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/3rd/VTK7.1/source/VTK-7.1.1/Utilities/MetaIO/vtkmetaio/metaFEMObject.cxx

1422 lines
40 KiB
C++

/*=========================================================================
*
* Copyright Insight Software Consortium
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#include "metaFEMObject.h"
#include <stdio.h>
#include <ctype.h>
#include <string>
#if (METAIO_USE_NAMESPACE)
namespace METAIO_NAMESPACE {
#endif
FEMObjectNode::
FEMObjectNode(int dim)
{
m_Dim = dim;
m_GN = -1;
m_X = new float[m_Dim];
for(unsigned int i=0;i<m_Dim;i++)
{
m_X[i] = 0;
}
}
FEMObjectNode::
~FEMObjectNode()
{
delete []m_X;
}
FEMObjectElement::
FEMObjectElement(int dim)
{
m_Dim = dim;
m_GN = -1;
m_NodesId = new int[m_Dim];
for(unsigned int i=0;i<m_Dim;i++)
{
m_NodesId[i] = -1;
}
}
FEMObjectElement::
~FEMObjectElement()
{
delete []m_NodesId;
}
FEMObjectLoad::FEMObjectLoad()
{
}
FEMObjectLoad::~FEMObjectLoad()
{
for(METAIO_STL::vector<FEMObjectMFCTerm *>::iterator it = this->m_LHS.begin();
it != this->m_LHS.end();
++it)
{
delete (*it);
}
this->m_LHS.clear();
this->m_RHS.clear();
this->m_ForceMatrix.clear();
this->m_ForceVector.clear();
}
//
// MetaFEMObject Constructors
//
MetaFEMObject::
MetaFEMObject()
:MetaObject()
{
if(META_DEBUG) METAIO_STREAM::cout << "MetaFEMObject()" << METAIO_STREAM::endl;
Clear();
this->m_ClassNameList.push_back("Node");
this->m_ClassNameList.push_back("MaterialLinearElasticity");
this->m_ClassNameList.push_back("Element2DC0LinearLineStress");
this->m_ClassNameList.push_back("Element2DC1Beam");
this->m_ClassNameList.push_back("Element2DC0LinearTriangularMembrane");
this->m_ClassNameList.push_back("Element2DC0LinearTriangularStrain");
this->m_ClassNameList.push_back("Element2DC0LinearTriangularStress");
this->m_ClassNameList.push_back("Element2DC0LinearQuadrilateralMembrane");
this->m_ClassNameList.push_back("Element2DC0LinearQuadrilateralStrain");
this->m_ClassNameList.push_back("Element2DC0LinearQuadrilateralStress");
this->m_ClassNameList.push_back("Element2DC0QuadraticTriangularStress");
this->m_ClassNameList.push_back("Element2DC0QuadraticTriangularStrain");
this->m_ClassNameList.push_back("Element3DC0LinearHexahedronMembrane");
this->m_ClassNameList.push_back("Element3DC0LinearHexahedronStrain");
this->m_ClassNameList.push_back("Element3DC0LinearTetrahedronMembrane");
this->m_ClassNameList.push_back("Element3DC0LinearTetrahedronStrain");
this->m_ClassNameList.push_back("LoadBC");
this->m_ClassNameList.push_back("LoadBCMFC");
this->m_ClassNameList.push_back("LoadNode");
this->m_ClassNameList.push_back("LoadEdge");
this->m_ClassNameList.push_back("LoadGravConst");
this->m_ClassNameList.push_back("LoadLandmark");
this->m_ClassNameList.push_back("LoadPoint");
this->m_ElementDataFileName = "LOCAL";
}
//
MetaFEMObject::
MetaFEMObject(const char *_headerName)
:MetaObject()
{
if(META_DEBUG)
{
METAIO_STREAM::cout << "MetaFEMObject()" << METAIO_STREAM::endl;
}
Clear();
Read(_headerName);
this->m_ElementDataFileName = "LOCAL";
}
//
MetaFEMObject::
MetaFEMObject(const MetaFEMObject *_mesh)
: MetaObject()
{
if(META_DEBUG)
{
METAIO_STREAM::cout << "MetaFEMObject()" << METAIO_STREAM::endl;
}
Clear();
CopyInfo(_mesh);
}
//
MetaFEMObject::
MetaFEMObject(unsigned int dim)
:MetaObject(dim)
{
if(META_DEBUG)
{
METAIO_STREAM::cout << "MetaFEMObject()" << METAIO_STREAM::endl;
}
Clear();
this->m_ElementDataFileName = "LOCAL";
}
/** Destructor */
MetaFEMObject::
~MetaFEMObject()
{
// Delete the list of pointers to Nodes.
NodeListType::iterator it_Node = m_NodeList.begin();
while(it_Node != m_NodeList.end())
{
FEMObjectNode* Node = *it_Node;
it_Node++;
delete Node;
}
// Delete the list of pointers to Materials.
MaterialListType::iterator it_Material = m_MaterialList.begin();
while(it_Material != m_MaterialList.end())
{
FEMObjectMaterial* Material = *it_Material;
it_Material++;
delete Material;
}
// Delete the list of pointers to Elements.
ElementListType::iterator it_Element = m_ElementList.begin();
while(it_Element != m_ElementList.end())
{
FEMObjectElement* Element = *it_Element;
it_Element++;
delete Element;
}
// Delete the list of pointers to Loads.
LoadListType::iterator it_Load = m_LoadList.begin();
while(it_Load != m_LoadList.end())
{
FEMObjectLoad* Load = *it_Load;
it_Load++;
delete Load;
}
M_Destroy();
}
//
void MetaFEMObject::
PrintInfo() const
{
MetaObject::PrintInfo();
}
void MetaFEMObject::
CopyInfo(const MetaObject * _object)
{
MetaObject::CopyInfo(_object);
}
/** Clear FEMObject information */
void MetaFEMObject::
Clear(void)
{
if(META_DEBUG)
{
METAIO_STREAM::cout << "MetaFEMObject: Clear" << METAIO_STREAM::endl;
}
MetaObject::Clear();
if(META_DEBUG)
{
METAIO_STREAM::cout << "MetaFEMObject: Clear: m_NPoints" << METAIO_STREAM::endl;
}
// Delete the list of pointers to Nodes.
NodeListType::iterator it_Node = m_NodeList.begin();
while(it_Node != m_NodeList.end())
{
FEMObjectNode* Node = *it_Node;
it_Node++;
delete Node;
}
// Delete the list of pointers to Elements.
ElementListType::iterator it_Element = m_ElementList.begin();
while(it_Element != m_ElementList.end())
{
FEMObjectElement* Element = *it_Element;
it_Element++;
delete Element;
}
// Delete the list of pointers to Loads.
LoadListType::iterator it_Load = m_LoadList.begin();
while(it_Load != m_LoadList.end())
{
FEMObjectLoad* Load = *it_Load;
it_Load++;
delete Load;
}
// Delete the list of pointers to Materials.
MaterialListType::iterator it_Material = m_MaterialList.begin();
while(it_Material != m_MaterialList.end())
{
FEMObjectMaterial* Material = *it_Material;
it_Material++;
delete Material;
}
m_NodeList.clear();
m_ElementList.clear();
m_LoadList.clear();
m_MaterialList.clear();
}
/** Destroy tube information */
void MetaFEMObject::
M_Destroy(void)
{
MetaObject::M_Destroy();
}
/** Set Read fields */
void MetaFEMObject::
M_SetupReadFields(void)
{
if(META_DEBUG)
{
METAIO_STREAM::cout << "MetaFEMObject: M_SetupReadFields" << METAIO_STREAM::endl;
}
MetaObject::M_SetupReadFields();
MET_FieldRecordType * mF;
mF = new MET_FieldRecordType;
MET_InitWriteField(mF, "ElementDataFile", MET_STRING, true);
mF->required = true;
mF->terminateRead = true;
m_Fields.push_back(mF);
}
void MetaFEMObject::
M_SetupWriteFields(void)
{
strcpy(m_ObjectTypeName,"FEMObject");
MetaObject::M_SetupWriteFields();
MET_FieldRecordType * mF;
mF = new MET_FieldRecordType;
MET_InitWriteField(mF, "ElementDataFile", MET_STRING,
m_ElementDataFileName.length(),
m_ElementDataFileName.c_str());
mF->terminateRead = true;
m_Fields.push_back(mF);
}
bool MetaFEMObject::
M_Read(void)
{
if(META_DEBUG)
{
METAIO_STREAM::cout << "MetaFEMObject: M_Read: Loading Header" << METAIO_STREAM::endl;
}
if(!MetaObject::M_Read())
{
METAIO_STREAM::cout << "MetaFEMObject: M_Read: Error parsing file" << METAIO_STREAM::endl;
return false;
}
if(META_DEBUG)
{
METAIO_STREAM::cout << "MetaFEMObject: M_Read: Parsing Header" << METAIO_STREAM::endl;
}
// currently reader handles only ASCII data
if(m_BinaryData)
{
METAIO_STREAM::cout << "MetaFEMObject: M_Read: Data content should be in ASCII format" << METAIO_STREAM::endl;
return false;
}
// we read 1)node, 2) material, 3) element and 4) load and the input should be in the afore
// mentioned order.
int segment_read = 0; // to keep track of what is being read. corresponds to enumerated types in the header file
/* then we start reading objects from stream */
do
{
// local variables
std::streampos l(0);
char buf[256];
std::string s;
std::string::size_type b, e;
bool clID;
std::string errorMessage;
if(segment_read > 3)
{
this->SkipWhiteSpace();
return true; // end of FEM segment in spatial object reader.
}
l = this->m_ReadStream->tellg(); // remember the stream position
this->SkipWhiteSpace(); // skip comments and whitespaces
if ( this->m_ReadStream->eof() )
{
return 0; // end of stream. all was good
}
char c;
if ( ( c = static_cast<char>(this->m_ReadStream->get()) ) != '<' )
{
std::string rest;
std::getline(*this->m_ReadStream, rest);
errorMessage = "Expected < token not found. Instead found '";
errorMessage += c;
errorMessage += "'.\nRest of line is '";
errorMessage += rest;
errorMessage += "'.\n";
METAIO_STREAM::cout << errorMessage << METAIO_STREAM::endl;
return false; // the file is not in proper format
}
this->m_ReadStream->getline(buf, 256, '>'); // read up to 256 characters until '>' is reached.
// we read and discard the '>'
s = std::string(buf);
// get rid of the whitespaces in front of and the back of token
b = s.find_first_not_of(this->whitespaces); // end of
// whitespaces
// in the
// beginning
if ( ( e = s.find_first_of(this->whitespaces, b) ) == std::string::npos ) //
// beginning
// of
// whitespaces
// at the
// end
{
e = s.size();
}
s = s.substr(b, e - b);
if ( s == "END" )
{
/*
* We can ignore this token. Start again by reading the next object.
*/
segment_read++;
}
else
{
clID = this->IsClassNamePresent(s); // obtain the class ID from FEMObjectFactory
if ( !clID)
{
errorMessage = s;
errorMessage += " is not a valid FEM data type";
errorMessage += "'.";
METAIO_STREAM::cout << errorMessage << METAIO_STREAM::endl;
return false; // class not found
}
/*
* Now we have to read additional data, which is
* specific to the class of object we just created
*/
switch ( segment_read )
{
case NODE :
this->M_Read_Node();
break;
case MATERIAL :
this->M_Read_Material(s);
break;
case ELEMENT :
this->M_Read_Element(s);
break;
case LOAD :
this->M_Read_Load(s);
break;
}
}
}while(segment_read <= 3); // end of FEM segment in spatial object reader.
return true;
}
bool MetaFEMObject::
M_Write(void)
{
if(!MetaObject::M_Write())
{
METAIO_STREAM::cout << "MetaFEMObject: M_Write: Error parsing file" << METAIO_STREAM::endl;
return false;
}
NodeListType::iterator it_Node = m_NodeList.begin();
while(it_Node != m_NodeList.end())
{
FEMObjectNode* Node = *it_Node;
this->M_Write_Node(Node);
it_Node++;
}
*this->m_WriteStream << "\n<END> % End of nodes\n\n";
MaterialListType::iterator it_Material = m_MaterialList.begin();
while(it_Material != m_MaterialList.end())
{
FEMObjectMaterial* Material = *it_Material;
this->M_Write_Material(Material);
it_Material++;
}
*this->m_WriteStream << "\n<END> % End of material definition\n\n";
ElementListType::iterator it_Element = m_ElementList.begin();
while(it_Element != m_ElementList.end())
{
FEMObjectElement* Element = *it_Element;
this->M_Write_Element(Element);
it_Element++;
}
*this->m_WriteStream << "\n<END> % End of element definition\n\n";
LoadListType::iterator it_Load = m_LoadList.begin();
while(it_Load != m_LoadList.end())
{
FEMObjectLoad* Load = *it_Load;
this->M_Write_Load(Load);
it_Load++;
}
*this->m_WriteStream << "\n<END> % End of load definition\n\n";
return true;
}
void MetaFEMObject::M_Write_Node(FEMObjectNode *Node)
{
// first write the class name
*this->m_WriteStream << '<' << "Node" << ">\n";
// then the global object number
*this->m_WriteStream << "\t" << Node->m_GN << "\t% Global object number\n";
/* write co-ordinate values */
*this->m_WriteStream << "\t" << Node->m_Dim;
for (unsigned int i=0; i<Node->m_Dim; i++)
{
*this->m_WriteStream << " " << Node->m_X[i];
}
*this->m_WriteStream << "\t% Node coordinates" << "\n";
}
void MetaFEMObject::M_Write_Material(FEMObjectMaterial *Material)
{
if(std::string(Material->m_MaterialName) == "MaterialLinearElasticity")
{
*this->m_WriteStream << '<' << "MaterialLinearElasticity" << ">\n";
*this->m_WriteStream << "\t" << Material->m_GN << "\t% Global object number\n";
*this->m_WriteStream << "\tE : " << Material->E << "\t% Young modulus\n";
*this->m_WriteStream << "\tA : " << Material->A << "\t% Beam crossection area\n";
*this->m_WriteStream << "\tI : " << Material->I << "\t% Moment of inertia\n";
*this->m_WriteStream << "\tnu : " << Material->nu << "\t% Poisson's ratio\n";
*this->m_WriteStream << "\th : " << Material->h << "\t% Plate thickness\n";
*this->m_WriteStream << "\tRhoC : " << Material->RhoC << "\t% Density times capacity\n";
*this->m_WriteStream << "\tEND:\t% End of material definition\n";
}
}
void MetaFEMObject::M_Write_Element(FEMObjectElement *Element)
{
*this->m_WriteStream << '<' << Element->m_ElementName << ">\n";
*this->m_WriteStream << "\t" << Element->m_GN << "\t% Global object number\n";
unsigned int numNodes = Element->m_NumNodes;
for ( unsigned int p = 0; p < numNodes; p++ )
{
*this->m_WriteStream << "\t" << Element->m_NodesId[p] << "\t% Node #" << ( p + 1 ) << " ID\n";
}
*this->m_WriteStream << "\t" << Element->m_MaterialGN << "\t% Material ID\n";
}
void MetaFEMObject::M_Write_Load(FEMObjectLoad *Load)
{
*this->m_WriteStream << '<' << Load->m_LoadName << ">\n";
*this->m_WriteStream << "\t" << Load->m_GN << "\t% Global object number\n";
// write according to the load type
if(std::string(Load->m_LoadName) == "LoadBC")
{
*this->m_WriteStream << "\t" << Load->m_ElementGN << "\t% GN of element" << "\n";
*this->m_WriteStream << "\t" << Load->m_DOF << "\t% DOF# in element" << "\n";
*this->m_WriteStream << "\t" << Load->m_NumRHS;
for (int i=0; i<Load->m_NumRHS; i++)
{
*this->m_WriteStream << " " << Load->m_RHS[i];
}
*this->m_WriteStream << "\t% value of the fixed DOF" << "\n";
return;
}
if(std::string(Load->m_LoadName) == "LoadNode")
{
*this->m_WriteStream << "\t" << Load->m_ElementGN << "\t% GN of element" << "\n";
*this->m_WriteStream << "\t" << Load->m_NodeNumber << " " << "\t% Point number within the element\n";
*this->m_WriteStream << "\t" << Load->m_Dim;
for (int i=0; i<Load->m_Dim; i++)
{
*this->m_WriteStream << " " << Load->m_ForceVector[i];
}
*this->m_WriteStream << "\t% Force vector (first number is the size of a vector)\n";
return;
}
if(std::string(Load->m_LoadName) == "LoadBCMFC")
{
/** write the number of DOFs affected by this MFC */
*this->m_WriteStream << "\t" << Load->m_NumLHS << "\t% Number of DOFs in this MFC" << std::endl;
/** write each term */
*this->m_WriteStream << "\t %==>\n";
for ( int i=0; i<Load->m_NumLHS; i++ )
{
FEMObjectMFCTerm *mfcTerm = dynamic_cast< FEMObjectMFCTerm * > (&*Load->m_LHS[i]);
*this->m_WriteStream << "\t " <<mfcTerm->m_ElementGN << "\t% GN of element" << std::endl;
*this->m_WriteStream << "\t " << mfcTerm->m_DOF << "\t% DOF# in element" << std::endl;
*this->m_WriteStream << "\t " << mfcTerm->m_Value << "\t% weight" << std::endl;
*this->m_WriteStream << "\t %==>\n";
}
/** write the rhs */
*this->m_WriteStream << "\t" << Load->m_NumRHS;
for ( int i=0; i<Load->m_NumRHS; i++ )
{
*this->m_WriteStream << " " << Load->m_RHS[i];
}
*this->m_WriteStream << "\t% rhs of MFC" << std::endl;
return;
}
if(std::string(Load->m_LoadName) == "LoadEdge")
{
*this->m_WriteStream << "\t" << Load->m_ElementGN << "\t% GN of the element on which the load acts" << "\n";
/** ... edge number */
*this->m_WriteStream << "\t" << Load->m_EdgeNumber << "\t% Edge number" << "\n";
/** ... force matrix */
size_t numRows = Load->m_ForceMatrix.size();
size_t numCols = Load->m_ForceMatrix[0].size();
*this->m_WriteStream << "\t" << numRows << "\t% # rows in force matrix" << "\n";
*this->m_WriteStream << "\t" << numCols << "\t% # cols in force matrix" << "\n";
*this->m_WriteStream << "\t% force matrix\n";
for ( size_t i = 0; i < numRows; i++ )
{
*this->m_WriteStream << "\t";
METAIO_STL::vector<float> F = Load->m_ForceMatrix[i];
for ( size_t j = 0; j < numCols; j++ )
{
*this->m_WriteStream << F[j] << " ";
}
*this->m_WriteStream << "\n";
}
return;
}
if(std::string(Load->m_LoadName) == "LoadGravConst")
{
/** Write the list of element global numbers */
if ( Load->m_NumElements > 0 )
{
*this->m_WriteStream << "\t" << Load->m_NumElements;
*this->m_WriteStream << "\t% # of elements on which the load acts" << std::endl;
*this->m_WriteStream << "\t";
for ( int i = 0; i < Load->m_NumElements; i++ )
{
*this->m_WriteStream << Load->m_Elements[i] << " ";
}
*this->m_WriteStream << "\t% GNs of elements" << std::endl;
}
else
{
*this->m_WriteStream << "\t-1\t% Load acts on all elements" << std::endl;
}
/** then write the actual data force vector */
*this->m_WriteStream << "\t" << Load->m_Dim << "\t% Size of the gravity force vector\n";
for (int i=0; i<Load->m_Dim; i++)
{
*this->m_WriteStream << "\t" << Load->m_ForceVector[i] ;
}
*this->m_WriteStream << "\t% Gravity force vector\n";
}
if(std::string(Load->m_LoadName) == "LoadLandmark")
{
// print undeformed coordinates
size_t dim = Load->m_Undeformed.size();
*this->m_WriteStream << "\t" << dim;
for ( size_t i = 0; i < dim; i++ )
{
*this->m_WriteStream << Load->m_Undeformed[i] << " ";
}
*this->m_WriteStream << "\t % Dimension , undeformed state local coordinates";
*this->m_WriteStream << "\n";
// print deformed coordinates
*this->m_WriteStream << "\t" << dim;
for ( size_t i = 0; i < dim; i++ )
{
*this->m_WriteStream << Load->m_Deformed[i] << " ";
}
*this->m_WriteStream << "\t % Dimension , deformed state local coordinates";
*this->m_WriteStream << "\n";
// print square root of Variance
*this->m_WriteStream << Load->m_Variance;
*this->m_WriteStream << "\t % Square root of the landmark variance ";
*this->m_WriteStream << "\n";
return;
}
}
void
MetaFEMObject::SkipWhiteSpace()
{
std::string skip;
while ( this->m_ReadStream && !this->m_ReadStream->eof() && ( std::ws(*this->m_ReadStream).peek() ) == '%' )
{
std::getline(*this->m_ReadStream, skip);
}
}
bool MetaFEMObject::IsClassNamePresent(std::string c_string)
{
ClassNameListType::const_iterator it = this->m_ClassNameList.begin();
while(it != this->m_ClassNameList.end())
{
if((*it) == c_string)
return true;
it++;
}
return false;
}
bool MetaFEMObject::M_Read_Node()
{
unsigned int n;
float coor[3];
/**
* First call the parent's read function
*/
int GN = this->ReadGlobalNumber();
if(GN == -1)
{
METAIO_STREAM::cout << "Error reading Global Number" << METAIO_STREAM::endl;
return false;
}
/*
* Read and set node coordinates
*/
// read dimensions
this->SkipWhiteSpace(); *this->m_ReadStream >> n;
if ( !this->m_ReadStream)
{
METAIO_STREAM::cout << "Error reading Node dimensions" << METAIO_STREAM::endl;
return false;
}
FEMObjectNode *node = new FEMObjectNode(n);
node->m_GN = GN;
this->SkipWhiteSpace();
for (unsigned int i = 0; i< n; i++)
{
*this->m_ReadStream >> coor[i];
if ( !this->m_ReadStream )
{
METAIO_STREAM::cout << "Error reading Node coordinates" << METAIO_STREAM::endl;
return false;
}
node->m_X[i] = coor[i];
}
this->m_NodeList.push_back(node);
return true;
}
bool MetaFEMObject::M_Read_Material(std::string material_name)
{
/**
* First call the parent's read function
*/
int GN = this->ReadGlobalNumber();
if(GN == -1)
{
METAIO_STREAM::cout << "Error reading Global Number" << METAIO_STREAM::endl;
return false;
}
/*
* Read material properties
*/
double d;
std::streampos l(0);
char buf[256];
std::string s;
std::string::size_type b, e;
// clear the data already inside the object
double E = 0.0; double A = 0.0; double I = 0.0;
double nu = 0.0; double h = 1.0; double RhoC = 1.0;
/*
* Next we read any known constant from stream. This allows a user to
* specify only constants which are actually required by elements in
* a system. This makes creating input files a bit easier.
*/
while ( this->m_ReadStream )
{
l = this->m_ReadStream->tellg(); // remember the stream position
this->SkipWhiteSpace(); // skip comments and whitespaces
/**
* All Constants are in the following format:
* constant_name : value
*/
this->m_ReadStream->getline(buf, 256, ':'); // read up to 256 characters until ':' is
// reached. we read and discard the ':'
if ( !this->m_ReadStream )
{
METAIO_STREAM::cout << "Error reading Material properties" << METAIO_STREAM::endl;
return false;
} // no : was found
s = std::string(buf);
// Get rid of the whitespaces in front of and the back of token
b = s.find_first_not_of(whitespaces); // end
// of
// whitespaces
// in
// the
// beginning
if ( ( e = s.find_first_of(whitespaces, b) ) == std::string::npos ) //
// beginning
// of
// whitespaces
// at
// the
// end
{
e = s.size();
}
/*
* s now contains just the name of the constant.
* The value is ready to be read next from the stream
*/
s = s.substr(b, e - b);
if ( s == "E" )
{
*this->m_ReadStream >> d;
if ( !this->m_ReadStream )
{
METAIO_STREAM::cout << "Error reading Material E property" << METAIO_STREAM::endl;
return false;
}
E = d;
continue;
}
if ( s == "A" )
{
*this->m_ReadStream >> d;
if ( !this->m_ReadStream )
{
METAIO_STREAM::cout << "Error reading Material A property" << METAIO_STREAM::endl;
return false;
}
A = d;
continue;
}
if ( s == "I" )
{
this->SkipWhiteSpace();
*this->m_ReadStream >> d;
if ( !this->m_ReadStream )
{
METAIO_STREAM::cout << "Error reading Material I property" << METAIO_STREAM::endl;
return false;
}
I = d;
continue;
}
if ( s == "nu" )
{
this->SkipWhiteSpace();
*this->m_ReadStream >> d;
if ( !this->m_ReadStream )
{
METAIO_STREAM::cout << "Error reading Material nu property" << METAIO_STREAM::endl;
return false;
}
nu = d;
continue;
}
if ( s == "h" )
{
this->SkipWhiteSpace();
*this->m_ReadStream >> d;
if ( !this->m_ReadStream )
{
METAIO_STREAM::cout << "Error reading Material h property" << METAIO_STREAM::endl;
return false;
}
h = d;
continue;
}
if ( s == "RhoC" )
{
this->SkipWhiteSpace();
*this->m_ReadStream >> d;
if ( !this->m_ReadStream )
{
METAIO_STREAM::cout << "Error reading Material RhoC property" << METAIO_STREAM::endl;
return false;
}
RhoC = d;
continue;
}
if ( s == "END" )
{
// End of constants in material definition
// store all the material definitions
FEMObjectMaterial *material = new FEMObjectMaterial();
strcpy(material->m_MaterialName, material_name.c_str());
material->m_GN = GN;
material->E = E;
material->A = A;
material->I = I;
material->nu = nu;
material->h = h;
material->RhoC = RhoC;
this->m_MaterialList.push_back(material);
break;
}
/**
* If we got here an unknown constant was reached.
* We reset the stream position and set the stream error.
*/
this->m_ReadStream->seekg(l);
this->m_ReadStream->clear(std::ios::failbit);
}
if ( !this->m_ReadStream )
{
METAIO_STREAM::cout << "Error reading Material properties" << METAIO_STREAM::endl;
return false;
}
return true;
}
bool MetaFEMObject::M_Read_Element(std::string element_name)
{
unsigned int n, materialGN;
int info[2];
this->GetElementDimensionAndNumberOfNodes(element_name, info);
int GN = this->ReadGlobalNumber();
if(GN == -1)
{
METAIO_STREAM::cout << "Error reading Global Number" << METAIO_STREAM::endl;
return false;
}
/*
* Read and set element connectivity
*/
int *NodesId = new int[info[0]];
for ( int p = 0; p < info[0]; p++ )
{
this->SkipWhiteSpace(); *this->m_ReadStream >> n;
if ( !this->m_ReadStream )
{
delete [] NodesId;
METAIO_STREAM::cout << "Error reading Element node numbers" << METAIO_STREAM::endl;
return false;
}
NodesId[p] = n;
}
// read material associated with the element
this->SkipWhiteSpace(); *this->m_ReadStream >> materialGN;
if ( !this->m_ReadStream )
{
delete [] NodesId;
METAIO_STREAM::cout << "Error reading Element global number" << METAIO_STREAM::endl;
return false;
}
// store the read information
FEMObjectElement *element = new FEMObjectElement(info[0]);
element->m_GN = GN;
for ( int p = 0; p < info[0]; p++ )
{
element->m_NodesId[p] = NodesId[p];
}
element->m_MaterialGN = materialGN;
element->m_NumNodes = info[0];
element->m_Dim = info[1];
strcpy(element->m_ElementName, element_name.c_str());
delete [] NodesId;
this->m_ElementList.push_back(element);
return true;
}
bool MetaFEMObject::M_Read_Load(std::string load_name)
{
int GN;
int elementGN;
int DOF;
int NumRHS;
int NodeNumber;
int Dim;
int NumLHS;
int Value;
FEMObjectLoad *load = new FEMObjectLoad;
strcpy(load->m_LoadName, load_name.c_str());
GN = this->ReadGlobalNumber();
if (GN == -1)
{
delete load;
METAIO_STREAM::cout << "Error reading Load definition - global number" << METAIO_STREAM::endl;
return false;
}
load->m_GN = GN;
if(load_name == "LoadBC")
{
/* read and set pointer to element that we're applying the load to */
this->SkipWhiteSpace();
*this->m_ReadStream >> elementGN;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading Load definition - Element Global Number" << METAIO_STREAM::endl;
return false;
}
load->m_ElementGN = elementGN;
/* read the local DOF number within that element */
this->SkipWhiteSpace();
*this->m_ReadStream >> DOF;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading Load definition - Degrees of Freedom" << METAIO_STREAM::endl;
return false;
}
load->m_DOF = DOF;
/* read the value to which the DOF is fixed */
this->SkipWhiteSpace();
*this->m_ReadStream >> NumRHS;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading Load definition - Number of fixed degrees of freedom" << METAIO_STREAM::endl;
return false;
}
load->m_NumRHS = NumRHS;
load->m_RHS.resize(NumRHS);
for (int i=0; i<NumRHS; i++)
{
this->SkipWhiteSpace();
*this->m_ReadStream >> load->m_RHS[i];
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading Load definition - Fixed degree of freedom" << METAIO_STREAM::endl;
return false;
}
}
}
else if(load_name == "LoadNode")
{
/* read and set pointer to element that we're applying the load to */
this->SkipWhiteSpace();
*this->m_ReadStream >> elementGN;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadNode definition - Element Global Number" << METAIO_STREAM::endl;
return false;
}
load->m_ElementGN = elementGN;
/* read the value to which the DOF is fixed */
this->SkipWhiteSpace();
*this->m_ReadStream >> NodeNumber;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadNode definition - Node Number" << METAIO_STREAM::endl;
return false;
}
load->m_NodeNumber = NodeNumber;
this->SkipWhiteSpace();
*this->m_ReadStream >> Dim;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadNode definition - Dimension" << METAIO_STREAM::endl;
return false;
}
load->m_Dim = Dim;
load->m_ForceVector.resize(Dim);
for (int i=0; i<Dim; i++)
{
this->SkipWhiteSpace();
*this->m_ReadStream >> load->m_ForceVector[i];
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadNode definition - Force Vector" << METAIO_STREAM::endl;
return false;
}
}
}
else if(load_name == "LoadBCMFC")
{
/** read number of terms in lhs of MFC equation */
this->SkipWhiteSpace();
*this->m_ReadStream >> NumLHS;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadBCMFC definition - Number of LHS terms" << METAIO_STREAM::endl;
return false;
}
load->m_NumLHS = NumLHS;
for ( int i = 0; i < NumLHS; i++ )
{
/** read and set pointer to element that we're applying the load to */
this->SkipWhiteSpace();
*this->m_ReadStream >> elementGN;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadBCMFC definition - Element Global Number" << METAIO_STREAM::endl;
return false;
}
/** read the number of dof within that element */
this->SkipWhiteSpace();
*this->m_ReadStream >> DOF;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadBCMFC definition - Element Degree of Freedom" << METAIO_STREAM::endl;
return false;
}
/** read weight */
this->SkipWhiteSpace();
*this->m_ReadStream >> Value;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadBCMFC definition - Weight" << METAIO_STREAM::endl;
return false;
}
/** add a new MFCTerm to the lhs */
FEMObjectMFCTerm *mfcTerm = new FEMObjectMFCTerm(elementGN, DOF, static_cast<float>(Value));
load->m_LHS.push_back(mfcTerm);
}
/** read the rhs */
this->SkipWhiteSpace();
*this->m_ReadStream >> NumRHS;
if (!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadBCMFC definition - Number of RHS terms" << METAIO_STREAM::endl;
return false;
}
load->m_NumRHS = NumRHS;
load->m_RHS.resize(NumRHS);
for (int i=0; i<NumRHS; i++)
{
this->SkipWhiteSpace();
*this->m_ReadStream >> load->m_RHS[i];
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadBCMFC definition - RHS Term" << METAIO_STREAM::endl;
return false;
}
}
}
else if(load_name == "LoadEdge")
{
int edgeNum, numRows, numCols;
/* read the global number of the element on which the load acts */
this->SkipWhiteSpace();
*this->m_ReadStream >> elementGN;
if (!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadEdge definition - Element Global Number" << METAIO_STREAM::endl;
return false;
}
load->m_ElementGN = elementGN;
/** ... edge number */
this->SkipWhiteSpace();
*this->m_ReadStream >> edgeNum;
if (!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadEdge definition - Edge Number" << METAIO_STREAM::endl;
return false;
}
load->m_EdgeNumber = edgeNum;
/** ... # of rows */
this->SkipWhiteSpace();
*this->m_ReadStream >> numRows;
if (!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadEdge definition - Number of Rows" << METAIO_STREAM::endl;
return false;
}
/** ... # of cols */
this->SkipWhiteSpace();
*this->m_ReadStream >> numCols;
if (!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadEdge definition - Number of Columns" << METAIO_STREAM::endl;
return false;
}
for ( int i = 0; i < numRows; i++ )
{
this->SkipWhiteSpace();
METAIO_STL::vector<float> F(numCols);
for ( int j = 0; j < numCols; j++ )
{
*this->m_ReadStream >> F[j];
if (!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadEdge definition - Force Matrix" << METAIO_STREAM::endl;
return false;
}
}
this->SkipWhiteSpace();
load->m_ForceMatrix.push_back(F);
}
}
else if(load_name == "LoadGravConst")
{
// read in the list of elements on which the load acts
this->SkipWhiteSpace();
*this->m_ReadStream >> load->m_NumElements ;
if (!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadGravConst definition - Number of Elements" << METAIO_STREAM::endl;
return false;
}
for (int i=0; i<load->m_NumElements; i++)
{
this->SkipWhiteSpace();
*this->m_ReadStream >> elementGN ;
if (!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadGravConst definition - Element Global Number" << METAIO_STREAM::endl;
return false;
}
load->m_Elements.push_back(elementGN);
}
/** first read and set the size of the vector */
this->SkipWhiteSpace();
*this->m_ReadStream >> load->m_Dim;
if (!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadGravConst definition - Dimension" << METAIO_STREAM::endl;
return false;
}
float loadcomp;
/** then the actual values */
for (int i=0; i<load->m_Dim; i++)
{
this->SkipWhiteSpace();
*this->m_ReadStream >> loadcomp;
if (!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading LoadGravConst definition - Force Vector" << METAIO_STREAM::endl;
return false;
}
load->m_ForceVector.push_back(loadcomp);
}
}
else if(load_name == "LoadLandmark")
{
this->SkipWhiteSpace();
int n1, n2;
// read the dimensions of the undeformed point and set the size of the point
// accordingly
this->SkipWhiteSpace();
*this->m_ReadStream >> n1; if ( !this->m_ReadStream ) { return false; }
load->m_Undeformed.resize(n1);
for (int i=0; i<n1; i++)
{
this->SkipWhiteSpace();
*this->m_ReadStream >> load->m_Undeformed[i];
std::cout << " " << load->m_Undeformed[i] << std::endl;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading Loadlandmark definition - Undeformed point" << METAIO_STREAM::endl;
return false;
}
}
// Read the dimensions of the deformed point and set the size of the point
// accordingly
this->SkipWhiteSpace();
*this->m_ReadStream >> n2; if ( !this->m_ReadStream ) { return false; }
load->m_Deformed.resize(n2);
for (int i=0; i<n2; i++)
{
this->SkipWhiteSpace();
*this->m_ReadStream >> load->m_Deformed[i];
std::cout << " " << load->m_Deformed[i] << std::endl;
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading Loadlandmark definition - Undeformed point" << METAIO_STREAM::endl;
return false;
}
}
// Verify that the undeformed and deformed points are of the same size.
if ( n1 != n2 )
{
delete load;
METAIO_STREAM::cout << "Error reading Loadlandmark definition - Undeformed point and deformed point should have same dimension" << METAIO_STREAM::endl;
return false;
}
// read the square root of the m_Variance associated with this landmark
this->SkipWhiteSpace();
*this->m_ReadStream >> load->m_Variance;
}
if(!this->m_ReadStream)
{
delete load;
METAIO_STREAM::cout << "Error reading Load definition" << METAIO_STREAM::endl;
return false;
}
this->m_LoadList.push_back(load);
return true;
}
int* MetaFEMObject::GetElementDimensionAndNumberOfNodes(std::string c_string, int info[2])
{
if((c_string == "Element2DC0LinearLineStress") || (c_string == "Element2DC1Beam"))
{
info[0] = 2;
info[1] = 2;
}
if((c_string == "Element2DC0LinearTriangularMembrane") ||
(c_string == "Element2DC0LinearTriangularStrain") ||
(c_string == "Element2DC0LinearTriangularStress"))
{
info[0] = 3;
info[1] = 2;
}
if((c_string == "Element2DC0LinearQuadrilateralMembrane") ||
(c_string == "Element2DC0LinearQuadrilateralStrain") ||
(c_string == "Element2DC0LinearQuadrilateralStress"))
{
info[0] = 4;
info[1] = 2;
}
if((c_string == "Element2DC0QuadraticTriangularStrain") ||
(c_string == "Element2DC0QuadraticTriangularStress"))
{
info[0] = 6;
info[1] = 2;
}
if((c_string == "Element3DC0LinearHexahedronMembrane") ||
(c_string == "Element3DC0LinearHexahedronStrain"))
{
info[0] = 8;
info[1] = 3;
}
if((c_string == "Element3DC0LinearTetrahedronMembrane") ||
(c_string == "Element3DC0LinearTetrahedronStrain"))
{
info[0] = 4;
info[1] = 3;
}
return info;
}
int MetaFEMObject::ReadGlobalNumber()
{
int n;
/** Read and set the global object number */
this->SkipWhiteSpace();
*this->m_ReadStream >> n;
if(this->m_ReadStream)
return n;
else
return -1;
}
// string containing all whitespace characters
const std::string
MetaFEMObject
:: whitespaces = " \t\n\r";
#if (METAIO_USE_NAMESPACE)
}
#endif