git-svn-id: http://svn.sintef.no/trondheim/IFEM/trunk@798 e10b68d5-8a6e-419e-a041-bce267b0401d
290 lines
8.1 KiB
C
290 lines
8.1 KiB
C
// $Id$
|
|
//==============================================================================
|
|
//!
|
|
//! \file SIMLinEl2D.C
|
|
//!
|
|
//! \date Dec 04 2010
|
|
//!
|
|
//! \author Knut Morten Okstad / SINTEF
|
|
//!
|
|
//! \brief Solution driver for 2D NURBS-based linear elastic FEM analysis.
|
|
//!
|
|
//==============================================================================
|
|
|
|
#include "SIMLinEl2D.h"
|
|
#include "LinearElasticity.h"
|
|
#include "FiniteDefElasticity/NonlinearElasticity.h"
|
|
#include "AnalyticSolutions.h"
|
|
#include "Functions.h"
|
|
#include "Utilities.h"
|
|
#include "Vec3Oper.h"
|
|
#include "Property.h"
|
|
#include "Tensor.h"
|
|
#include "AnaSol.h"
|
|
#include <string.h>
|
|
|
|
|
|
SIMLinEl2D::SIMLinEl2D (int form, bool planeStress)
|
|
{
|
|
switch (form)
|
|
{
|
|
case SIM::LINEAR:
|
|
myProblem = new LinearElasticity(2,planeStress);
|
|
break;
|
|
case SIM::NONLINEAR:
|
|
myProblem = new NonlinearElasticity(2,planeStress);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
bool SIMLinEl2D::parse (char* keyWord, std::istream& is)
|
|
{
|
|
char* cline = 0;
|
|
Elasticity* elp = dynamic_cast<Elasticity*>(myProblem);
|
|
if (!elp) return false;
|
|
|
|
if (!strncasecmp(keyWord,"GRAVITY",7))
|
|
{
|
|
double gx = atof(strtok(keyWord+7," "));
|
|
double gy = atof(strtok(NULL," "));
|
|
elp->setGravity(gx,gy);
|
|
if (myPid == 0)
|
|
std::cout <<"\nGravitation vector: "
|
|
<< gx <<" "<< gy << std::endl;
|
|
}
|
|
|
|
else if (!strncasecmp(keyWord,"ISOTROPHIC",10))
|
|
{
|
|
int nmat = atoi(keyWord+10);
|
|
if (myPid == 0)
|
|
std::cout <<"\nNumber of isotrophic materials: "<< nmat << std::endl;
|
|
|
|
for (int i = 0; i < nmat && (cline = utl::readLine(is)); i++)
|
|
{
|
|
int code = atoi(strtok(cline," "));
|
|
double E = atof(strtok(NULL," "));
|
|
double nu = atof(strtok(NULL," "));
|
|
double rho = atof(strtok(NULL," "));
|
|
if (myPid == 0)
|
|
std::cout <<"\tMaterial code "<< code <<": "
|
|
<< E <<" "<< nu <<" "<< rho << std::endl;
|
|
if (code == 0 || i == 0)
|
|
elp->setMaterial(E,nu,rho);
|
|
for (size_t j = 0; j < myProps.size() && code > 0; j++)
|
|
if (myProps[j].pindx == (size_t)code &&
|
|
myProps[j].pcode == Property::UNDEFINED)
|
|
{
|
|
myProps[j].pindx = mVec.size();
|
|
myProps[j].pcode = Property::MATERIAL;
|
|
}
|
|
if (code > 0)
|
|
mVec.push_back(IsoMat(E,nu,rho));
|
|
}
|
|
}
|
|
|
|
else if (!strncasecmp(keyWord,"CONSTANT_PRESSURE",17))
|
|
{
|
|
int npres = atoi(keyWord+17);
|
|
if (myPid == 0)
|
|
std::cout <<"\nNumber of pressures: "<< npres << std::endl;
|
|
|
|
for (int i = 0; i < npres && (cline = utl::readLine(is)); i++)
|
|
{
|
|
int code = atoi(strtok(cline," "));
|
|
int pdir = atoi(strtok(NULL," "));
|
|
double p = atof(strtok(NULL," "));
|
|
if (myPid == 0)
|
|
std::cout <<"\tPressure code "<< code <<" direction "<< pdir
|
|
<<": "<< p << std::endl;
|
|
|
|
this->setPropertyType(code,Property::NEUMANN);
|
|
myTracs[code] = new PressureField(p,pdir);
|
|
}
|
|
}
|
|
|
|
else if (!strncasecmp(keyWord,"ANASOL",6))
|
|
{
|
|
cline = strtok(keyWord+6," ");
|
|
if (!strncasecmp(cline,"HOLE",4))
|
|
{
|
|
double a = atof(strtok(NULL," "));
|
|
double F0 = atof(strtok(NULL," "));
|
|
double nu = atof(strtok(NULL," "));
|
|
mySol = new AnaSol(new Hole(a,F0,nu));
|
|
std::cout <<"\nAnalytical solution: Hole a="<< a <<" F0="<< F0
|
|
<<" nu="<< nu << std::endl;
|
|
}
|
|
else if (!strncasecmp(cline,"LSHAPE",6))
|
|
{
|
|
double a = atof(strtok(NULL," "));
|
|
double F0 = atof(strtok(NULL," "));
|
|
double nu = atof(strtok(NULL," "));
|
|
mySol = new AnaSol(new Lshape(a,F0,nu));
|
|
std::cout <<"\nAnalytical solution: Lshape a="<< a <<" F0="<< F0
|
|
<<" nu="<< nu << std::endl;
|
|
}
|
|
else if (!strncasecmp(cline,"CANTS",5))
|
|
{
|
|
double L = atof(strtok(NULL," "));
|
|
double H = atof(strtok(NULL," "));
|
|
double F0 = atof(strtok(NULL," "));
|
|
mySol = new AnaSol(new CanTS(L,H,F0));
|
|
std::cout <<"\nAnalytical solution: CanTS L="<< L <<" H="<< H
|
|
<<" F0="<< F0 << std::endl;
|
|
}
|
|
else if (!strncasecmp(cline,"CANTM",5))
|
|
{
|
|
double H = atof(strtok(NULL," "));
|
|
double M0 = atof(strtok(NULL," "));
|
|
mySol = new AnaSol(new CanTM(H,M0));
|
|
std::cout <<"\nAnalytical solution: CanTM H="<< H
|
|
<<" M0="<< M0 << std::endl;
|
|
}
|
|
else if (!strncasecmp(cline,"CURVED",6))
|
|
{
|
|
double a = atof(strtok(NULL," "));
|
|
double b = atof(strtok(NULL," "));
|
|
double u0 = atof(strtok(NULL," "));
|
|
double E = atof(strtok(NULL," "));
|
|
mySol = new AnaSol(new CurvedBeam(u0,a,b,E));
|
|
std::cout <<"\nAnalytical solution: Curved Beam a="<< a <<" b="<< b
|
|
<<" u0="<< u0 <<" E="<< E << std::endl;
|
|
}
|
|
else
|
|
{
|
|
std::cerr <<" ** SIMLinEl2D::parse: Unknown analytical solution "
|
|
<< cline <<" (ignored)"<< std::endl;
|
|
return true;
|
|
}
|
|
|
|
// Define the analytical boundary traction field
|
|
int code = (cline = strtok(NULL," ")) ? atoi(cline) : 0;
|
|
if (code > 0 && mySol->getStressSol())
|
|
{
|
|
std::cout <<"Pressure code "<< code <<": Analytical traction"<< std::endl;
|
|
this->setPropertyType(code,Property::NEUMANN);
|
|
myTracs[code] = new TractionField(*mySol->getStressSol());
|
|
}
|
|
}
|
|
|
|
// The remaining keywords are retained for backward compatibility with the
|
|
// prototype version. They enable direct specification of properties onto
|
|
// the topological entities (blocks and faces) of the model.
|
|
|
|
else if (!strncasecmp(keyWord,"PRESSURE",8))
|
|
{
|
|
Property press;
|
|
press.pcode = Property::NEUMANN;
|
|
press.ldim = 1;
|
|
|
|
int npres = atoi(keyWord+8);
|
|
std::cout <<"\nNumber of pressures: "<< npres << std::endl;
|
|
for (int i = 0; i < npres && (cline = utl::readLine(is)); i++)
|
|
{
|
|
press.pindx = 1+i;
|
|
press.patch = atoi(strtok(cline," "));
|
|
|
|
int pid = this->getLocalPatchIndex(press.patch);
|
|
if (pid < 0) return false;
|
|
if (pid < 1) continue;
|
|
|
|
press.lindx = atoi(strtok(NULL," "));
|
|
if (press.lindx < 1 || press.lindx > 4)
|
|
{
|
|
std::cerr <<" *** SIMLinEl2D::parse: Invalid edge index "
|
|
<< (int)press.lindx << std::endl;
|
|
return false;
|
|
}
|
|
|
|
if (mySol && mySol->getStressSol())
|
|
{
|
|
std::cout <<"\tTraction on P"<< press.patch
|
|
<<" E"<< (int)press.lindx << std::endl;
|
|
myTracs[1+i] = new TractionField(*mySol->getStressSol());
|
|
}
|
|
else
|
|
{
|
|
int pdir = atoi(strtok(NULL," "));
|
|
double p = atof(strtok(NULL," "));
|
|
std::cout <<"\tPressure on P"<< press.patch
|
|
<<" E"<< (int)press.lindx <<" direction "<< pdir <<": ";
|
|
if ((cline = strtok(NULL," ")))
|
|
myTracs[1+i] = new PressureField(utl::parseRealFunc(cline,p),pdir);
|
|
else
|
|
{
|
|
std::cout << p;
|
|
myTracs[1+i] = new PressureField(p,pdir);
|
|
}
|
|
std::cout << std::endl;
|
|
}
|
|
|
|
press.patch = pid;
|
|
myProps.push_back(press);
|
|
}
|
|
}
|
|
|
|
else if (!strncasecmp(keyWord,"MATERIAL",8))
|
|
{
|
|
int nmat = atoi(keyWord+8);
|
|
std::cout <<"\nNumber of materials: "<< nmat << std::endl;
|
|
for (int i = 0; i < nmat && (cline = utl::readLine(is)); i++)
|
|
{
|
|
double E = atof(strtok(cline," "));
|
|
double nu = atof(strtok(NULL," "));
|
|
double rho = atof(strtok(NULL," "));
|
|
while ((cline = strtok(NULL," ")))
|
|
if (!strncasecmp(cline,"ALL",3))
|
|
{
|
|
std::cout <<"\tMaterial for all patches: "
|
|
<< E <<" "<< nu <<" "<< rho << std::endl;
|
|
elp->setMaterial(E,nu,rho);
|
|
}
|
|
else
|
|
{
|
|
int patch = atoi(cline);
|
|
int pid = this->getLocalPatchIndex(patch);
|
|
if (pid < 0) return false;
|
|
if (pid < 1) continue;
|
|
|
|
std::cout <<"\tMaterial for P"<< patch
|
|
<<": "<< E <<" "<< nu <<" "<< rho << std::endl;
|
|
myProps.push_back(Property(Property::MATERIAL,mVec.size(),pid,3));
|
|
mVec.push_back(IsoMat(E,nu,rho));
|
|
if (i == 0)
|
|
elp->setMaterial(E,nu,rho);
|
|
}
|
|
}
|
|
}
|
|
|
|
else
|
|
return this->SIM2D::parse(keyWord,is);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool SIMLinEl2D::initMaterial (size_t propInd)
|
|
{
|
|
Elasticity* elp = dynamic_cast<Elasticity*>(myProblem);
|
|
if (!elp) return false;
|
|
|
|
if (propInd >= mVec.size()) propInd = mVec.size()-1;
|
|
|
|
elp->setMaterial(mVec[propInd].E,mVec[propInd].nu,mVec[propInd].rho);
|
|
return true;
|
|
}
|
|
|
|
|
|
bool SIMLinEl2D::initNeumann (size_t propInd)
|
|
{
|
|
TracFuncMap::const_iterator tit = myTracs.find(propInd);
|
|
if (tit == myTracs.end()) return false;
|
|
|
|
Elasticity* elp = dynamic_cast<Elasticity*>(myProblem);
|
|
if (!elp) return false;
|
|
|
|
elp->setTraction(tit->second);
|
|
return true;
|
|
}
|