Added support for the <neumann> XML tag on SIMbase level within the

<boundaryconditions> tag. The new tag takes all the old formats for
specifying surface pressure variations in addition to expressions.
This makes the <constantpressure> and <linearpressure> tags in the
elasticity solver obsolete and have therefore been removed.

Function expressions are now also available for Dirichlet conditions.

git-svn-id: http://svn.sintef.no/trondheim/IFEM/trunk@1558 e10b68d5-8a6e-419e-a041-bce267b0401d
This commit is contained in:
kmo 2012-03-27 12:44:57 +00:00 committed by Knut Morten Okstad
parent 66aeb877de
commit 40ed14a9e1
12 changed files with 181 additions and 103 deletions

View File

@ -187,7 +187,7 @@ bool NonlinearElasticityTL::evalBou (LocalIntegral& elmInt,
const FiniteElement& fe, const FiniteElement& fe,
const Vec3& X, const Vec3& normal) const const Vec3& X, const Vec3& normal) const
{ {
if (!tracFld) if (!tracFld && !fluxFld)
{ {
std::cerr <<" *** NonlinearElasticityTL::evalBou: No tractions." std::cerr <<" *** NonlinearElasticityTL::evalBou: No tractions."
<< std::endl; << std::endl;
@ -203,15 +203,18 @@ bool NonlinearElasticityTL::evalBou (LocalIntegral& elmInt,
ElmMats& elMat = static_cast<ElmMats&>(elmInt); ElmMats& elMat = static_cast<ElmMats&>(elmInt);
// Evaluate the surface traction // Evaluate the surface traction
Vec3 T = (*tracFld)(X,normal); Vec3 T = this->getTraction(X,normal);
// Store traction value for visualization // Store traction value for visualization
if (fe.iGP < tracVal.size()) if (fe.iGP < tracVal.size() && !T.isZero())
if (!T.isZero()) tracVal[fe.iGP] = std::make_pair(X,T); {
tracVal[fe.iGP].first = X;
tracVal[fe.iGP].second += T;
}
// Check for with-rotated pressure load // Check for with-rotated pressure load
unsigned short int i, j; unsigned short int i, j;
if (tracFld->isNormalPressure()) if (tracFld && tracFld->isNormalPressure())
{ {
// Compute the deformation gradient, F // Compute the deformation gradient, F
Matrix B; Matrix B;

View File

@ -258,7 +258,7 @@ bool NonlinearElasticityUL::evalBou (LocalIntegral& elmInt,
const FiniteElement& fe, const FiniteElement& fe,
const Vec3& X, const Vec3& normal) const const Vec3& X, const Vec3& normal) const
{ {
if (!tracFld) if (!tracFld && !fluxFld)
{ {
std::cerr <<" *** NonlinearElasticityUL::evalBou: No tractions." std::cerr <<" *** NonlinearElasticityUL::evalBou: No tractions."
<< std::endl; << std::endl;
@ -272,11 +272,14 @@ bool NonlinearElasticityUL::evalBou (LocalIntegral& elmInt,
} }
// Evaluate the surface traction // Evaluate the surface traction
Vec3 T = (*tracFld)(X,normal); Vec3 T = this->getTraction(X,normal);
// Store traction value for visualization // Store traction value for visualization
if (fe.iGP < tracVal.size()) if (fe.iGP < tracVal.size() && !T.isZero())
if (!T.isZero()) tracVal[fe.iGP] = std::make_pair(X,T); {
tracVal[fe.iGP].first = X;
tracVal[fe.iGP].second += T;
}
// Axi-symmetric integration point volume; 2*pi*r*|J|*w // Axi-symmetric integration point volume; 2*pi*r*|J|*w
double detJW = axiSymmetry ? 2.0*M_PI*X.x*fe.detJxW : fe.detJxW; double detJW = axiSymmetry ? 2.0*M_PI*X.x*fe.detJxW : fe.detJxW;
@ -290,7 +293,7 @@ bool NonlinearElasticityUL::evalBou (LocalIntegral& elmInt,
return false; return false;
// Check for with-rotated pressure load // Check for with-rotated pressure load
if (tracFld->isNormalPressure()) if (tracFld && tracFld->isNormalPressure())
{ {
// Compute its inverse and determinant, J // Compute its inverse and determinant, J
double J = F.inverse(); double J = F.inverse();

View File

@ -301,26 +301,6 @@ bool SIMLinEl2D::parse (const TiXmlElement* elem)
<< E <<" "<< nu <<" "<< rho << std::endl; << E <<" "<< nu <<" "<< rho << std::endl;
} }
else if (!strcasecmp(child->Value(),"constantpressure") ||
!strcasecmp(child->Value(),"linearpressure")) {
if (child->FirstChild() && child->FirstChild()->Value()) {
double p = atof(child->FirstChild()->Value());
int code = 0, pdir = 1;
utl::getAttribute(child,"code",code);
utl::getAttribute(child,"dir",pdir);
setPropertyType(code,Property::NEUMANN);
if (!strcasecmp(child->Value(),"linearpressure")) {
RealFunc* pfl = new ConstTimeFunc(new LinearFunc(p));
myTracs[code] = new PressureField(pfl,pdir);
}
else
myTracs[code] = new PressureField(p,pdir);
if (myPid == 0)
std::cout <<"\tPressure code "<< code <<" direction "<< pdir
<<": "<< p << std::endl;
}
}
else if (!strcasecmp(child->Value(),"anasol")) { else if (!strcasecmp(child->Value(),"anasol")) {
std::string type; std::string type;
utl::getAttribute(child,"type",type,true); utl::getAttribute(child,"type",type,true);
@ -436,12 +416,18 @@ bool SIMLinEl2D::initMaterial (size_t propInd)
bool SIMLinEl2D::initNeumann (size_t propInd) 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); Elasticity* elp = dynamic_cast<Elasticity*>(myProblem);
if (!elp) return false; if (!elp) return false;
elp->setTraction(tit->second); VecFuncMap::const_iterator vit = myVectors.find(propInd);
TracFuncMap::const_iterator tit = myTracs.find(propInd);
if (vit != myVectors.end())
elp->setTraction(vit->second);
else if (tit != myTracs.end())
elp->setTraction(tit->second);
else
return false;
return true; return true;
} }

View File

@ -433,26 +433,6 @@ bool SIMLinEl3D::parse (const TiXmlElement* elem)
<< E <<" "<< nu <<" "<< rho << std::endl; << E <<" "<< nu <<" "<< rho << std::endl;
} }
else if (!strcasecmp(child->Value(),"constantpressure") ||
!strcasecmp(child->Value(),"linearpressure")) {
if (child->FirstChild() && child->FirstChild()->Value()) {
double p = atof(child->FirstChild()->Value());
int code = 0, pdir = 1;
utl::getAttribute(child,"code",code);
utl::getAttribute(child,"dir",pdir);
setPropertyType(code,Property::NEUMANN);
if (!strcasecmp(child->Value(),"linearpressure")) {
RealFunc* pfl = new ConstTimeFunc(new LinearFunc(p));
myTracs[code] = new PressureField(pfl,pdir);
}
else
myTracs[code] = new PressureField(p,pdir);
if (myPid == 0)
std::cout <<"\tPressure code "<< code <<" direction "<< pdir
<<": "<< p << std::endl;
}
}
else if (!strcasecmp(child->Value(),"anasol")) { else if (!strcasecmp(child->Value(),"anasol")) {
std::string type; std::string type;
utl::getAttribute(child,"type",type,true); utl::getAttribute(child,"type",type,true);
@ -564,12 +544,18 @@ bool SIMLinEl3D::initMaterial (size_t propInd)
bool SIMLinEl3D::initNeumann (size_t propInd) bool SIMLinEl3D::initNeumann (size_t propInd)
{ {
TracFuncMap::const_iterator tit = myTracs.find(propInd);
if (tit == myTracs.end()) return false;
Elasticity* elp = dynamic_cast<Elasticity*>(myProblem); Elasticity* elp = dynamic_cast<Elasticity*>(myProblem);
if (!elp) return false; if (!elp) return false;
elp->setTraction(tit->second); VecFuncMap::const_iterator vit = myVectors.find(propInd);
TracFuncMap::const_iterator tit = myTracs.find(propInd);
if (vit != myVectors.end())
elp->setTraction(vit->second);
else if (tit != myTracs.end())
elp->setTraction(tit->second);
else
return false;
return true; return true;
} }

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Pipe joint with shear-loaded brace.
Static linear-elastic analysis.
10-patch model, cubic Lagrange elements. !-->
<simulation>
<discretization type="Lagrange"/>
<geometry>
<patchfile>pipe_bifurcation.g2</patchfile>
<nodefile>pipe_bifurcation.gno</nodefile>
</geometry>
<boundaryconditions>
<propertyfile>pipe_bifurcation.prc</propertyfile>
<dirichlet code="123"/>
<neumann code="1001" direction="1">1.0e8</neumann>
</boundaryconditions>
<postprocessing>
<vtfformat>BINARY</vtfformat>
</postprocessing>
</simulation>

View File

@ -41,6 +41,7 @@ Elasticity::Elasticity (unsigned short int n, bool ax) : nsd(n), axiSymmetry(ax)
material = 0; material = 0;
locSys = 0; locSys = 0;
tracFld = 0; tracFld = 0;
fluxFld = 0;
bodyFld = 0; bodyFld = 0;
eM = eKm = eKg = 0; eM = eKm = eKg = 0;
eS = iS = 0; eS = iS = 0;
@ -173,7 +174,9 @@ LocalIntegral* Elasticity::getLocalIntegral (size_t nen, size_t,
Vec3 Elasticity::getTraction (const Vec3& X, const Vec3& n) const Vec3 Elasticity::getTraction (const Vec3& X, const Vec3& n) const
{ {
if (tracFld) if (fluxFld)
return (*fluxFld)(X);
else if (tracFld)
return (*tracFld)(X,n); return (*tracFld)(X,n);
else else
return Vec3(); return Vec3();
@ -195,6 +198,7 @@ Vec3 Elasticity::getBodyforce (const Vec3& X) const
bool Elasticity::haveLoads () const bool Elasticity::haveLoads () const
{ {
if (tracFld) return true; if (tracFld) return true;
if (fluxFld) return true;
if (bodyFld) return true; if (bodyFld) return true;
for (unsigned short int i = 0; i < nsd; i++) for (unsigned short int i = 0; i < nsd; i++)
@ -208,6 +212,7 @@ bool Elasticity::haveLoads () const
void Elasticity::initIntegration (size_t, size_t nBp) void Elasticity::initIntegration (size_t, size_t nBp)
{ {
tracVal.clear();
tracVal.resize(nBp,std::make_pair(Vec3(),Vec3())); tracVal.resize(nBp,std::make_pair(Vec3(),Vec3()));
} }

View File

@ -45,6 +45,8 @@ public:
//! \brief Defines the traction field to use in Neumann boundary conditions. //! \brief Defines the traction field to use in Neumann boundary conditions.
void setTraction(TractionFunc* tf) { tracFld = tf; } void setTraction(TractionFunc* tf) { tracFld = tf; }
//! \brief Defines the traction field to use in Neumann boundary conditions.
void setTraction(VecFunc* tf) { fluxFld = tf; }
//! \brief Defines the body force field. //! \brief Defines the body force field.
void setBodyForce(VecFunc* bf) { bodyFld = bf; } void setBodyForce(VecFunc* bf) { bodyFld = bf; }
@ -216,7 +218,8 @@ protected:
double grav[3]; //!< Gravitation vector double grav[3]; //!< Gravitation vector
LocalSystem* locSys; //!< Local coordinate system for result output LocalSystem* locSys; //!< Local coordinate system for result output
TractionFunc* tracFld; //!< Pointer to boundary traction field TractionFunc* tracFld; //!< Pointer to implicit boundary traction field
VecFunc* fluxFld; //!< Pointer to explicit boundary traction field
VecFunc* bodyFld; //!< Pointer to body force field VecFunc* bodyFld; //!< Pointer to body force field
mutable std::vector<Vec3Pair> tracVal; //!< Traction field point values mutable std::vector<Vec3Pair> tracVal; //!< Traction field point values

View File

@ -92,7 +92,7 @@ bool LinearElasticity::evalInt (LocalIntegral& elmInt, const FiniteElement& fe,
bool LinearElasticity::evalBou (LocalIntegral& elmInt, const FiniteElement& fe, bool LinearElasticity::evalBou (LocalIntegral& elmInt, const FiniteElement& fe,
const Vec3& X, const Vec3& normal) const const Vec3& X, const Vec3& normal) const
{ {
if (!tracFld) if (!tracFld && !fluxFld)
{ {
std::cerr <<" *** LinearElasticity::evalBou: No tractions."<< std::endl; std::cerr <<" *** LinearElasticity::evalBou: No tractions."<< std::endl;
return false; return false;
@ -107,11 +107,14 @@ bool LinearElasticity::evalBou (LocalIntegral& elmInt, const FiniteElement& fe,
const double detJW = axiSymmetry ? 2.0*M_PI*X.x*fe.detJxW : fe.detJxW; const double detJW = axiSymmetry ? 2.0*M_PI*X.x*fe.detJxW : fe.detJxW;
// Evaluate the surface traction // Evaluate the surface traction
Vec3 T = (*tracFld)(X,normal); Vec3 T = this->getTraction(X,normal);
// Store traction value for visualization // Store traction value for visualization
if (fe.iGP < tracVal.size()) if (fe.iGP < tracVal.size() && !T.isZero())
if (!T.isZero()) tracVal[fe.iGP] = std::make_pair(X,T); {
tracVal[fe.iGP].first = X;
tracVal[fe.iGP].second += T;
}
// Integrate the force vector // Integrate the force vector
Vector& ES = static_cast<ElmMats&>(elmInt).b[eS-1]; Vector& ES = static_cast<ElmMats&>(elmInt).b[eS-1];

View File

@ -29,6 +29,7 @@ Poisson::Poisson (unsigned short int n) : nsd(n)
kappa = 1.0; kappa = 1.0;
tracFld = 0; tracFld = 0;
fluxFld = 0;
heatSrc = 0; heatSrc = 0;
// Only the current solution is needed // Only the current solution is needed
@ -44,7 +45,12 @@ double Poisson::getHeat (const Vec3& X) const
double Poisson::getTraction (const Vec3& X, const Vec3& n) const double Poisson::getTraction (const Vec3& X, const Vec3& n) const
{ {
return tracFld ? (*tracFld)(X)*n : 0.0; if (fluxFld)
return (*fluxFld)(X);
else if (tracFld)
return (*tracFld)(X)*n;
else
return 0.0;
} }
@ -115,7 +121,7 @@ bool Poisson::evalInt (LocalIntegral& elmInt, const FiniteElement& fe,
bool Poisson::evalBou (LocalIntegral& elmInt, const FiniteElement& fe, bool Poisson::evalBou (LocalIntegral& elmInt, const FiniteElement& fe,
const Vec3& X, const Vec3& normal) const const Vec3& X, const Vec3& normal) const
{ {
if (!tracFld) if (!tracFld && !fluxFld)
{ {
std::cerr <<" *** Poisson::evalBou: No tractions."<< std::endl; std::cerr <<" *** Poisson::evalBou: No tractions."<< std::endl;
return false; return false;
@ -128,16 +134,15 @@ bool Poisson::evalBou (LocalIntegral& elmInt, const FiniteElement& fe,
return false; return false;
} }
// Evaluate the heat flux q at point X // Evaluate the Neumann value -q(X)*n
Vec3 q = (*tracFld)(X); double trac = -this->getTraction(X,normal);
// Evaluate the Neumann value -q*n
double trac = -(q*normal);
// Store traction value for visualization // Store traction value for visualization
if (fe.iGP < tracVal.size()) if (fe.iGP < tracVal.size() && abs(trac) > 1.0e8)
if (abs(trac) > 1.0e8) {
tracVal[fe.iGP] = std::make_pair(X,trac*normal); tracVal[fe.iGP].first = X;
tracVal[fe.iGP].second += trac*normal;
}
// Integrate the Neumann value // Integrate the Neumann value
elMat.b.front().add(fe.N,trac*fe.detJxW); elMat.b.front().add(fe.N,trac*fe.detJxW);
@ -148,6 +153,7 @@ bool Poisson::evalBou (LocalIntegral& elmInt, const FiniteElement& fe,
void Poisson::initIntegration (size_t, size_t nBp) void Poisson::initIntegration (size_t, size_t nBp)
{ {
tracVal.clear();
tracVal.resize(nBp,std::make_pair(Vec3(),Vec3())); tracVal.resize(nBp,std::make_pair(Vec3(),Vec3()));
} }

View File

@ -35,6 +35,8 @@ public:
//! \brief Defines the traction field to use in Neumann boundary conditions. //! \brief Defines the traction field to use in Neumann boundary conditions.
void setTraction(VecFunc* tf) { tracFld = tf; } void setTraction(VecFunc* tf) { tracFld = tf; }
//! \brief Defines the traction field to use in Neumann boundary conditions.
void setTraction(RealFunc* ff) { fluxFld = ff; }
//! \brief Defines the heat source field. //! \brief Defines the heat source field.
void setSource(RealFunc* src) { heatSrc = src; } void setSource(RealFunc* src) { heatSrc = src; }
@ -135,6 +137,7 @@ private:
protected: protected:
VecFunc* tracFld; //!< Pointer to boundary traction field VecFunc* tracFld; //!< Pointer to boundary traction field
RealFunc* fluxFld; //!< Pointer to boundary normal flux field
RealFunc* heatSrc; //!< Pointer to interior heat source RealFunc* heatSrc; //!< Pointer to interior heat source
mutable std::vector<Vec3Pair> tracVal; //!< Traction field point values mutable std::vector<Vec3Pair> tracVal; //!< Traction field point values

View File

@ -84,7 +84,7 @@ SIMbase::~SIMbase ()
delete *i1; delete *i1;
myModel.clear(); myModel.clear();
this->clearProperties(); this->SIMbase::clearProperties();
#ifdef SP_DEBUG #ifdef SP_DEBUG
std::cout <<"Leaving SIMbase destructor"<< std::endl; std::cout <<"Leaving SIMbase destructor"<< std::endl;
@ -149,7 +149,7 @@ bool SIMbase::parseGeometryTag (const TiXmlElement* elem)
int proc = 0; int proc = 0;
if (!utl::getAttribute(elem,"procs",proc)) if (!utl::getAttribute(elem,"procs",proc))
return false; return false;
if (proc != nProc) // silently ignore else if (proc != nProc) // silently ignore
return true; return true;
if (myPid == 0) if (myPid == 0)
std::cout <<"\tNumber of partitions: "<< nProc << std::endl; std::cout <<"\tNumber of partitions: "<< nProc << std::endl;
@ -231,21 +231,36 @@ bool SIMbase::parseBCTag (const TiXmlElement* elem)
} }
} }
else if (!strcasecmp(elem->Value(),"neumann")) {
int code = 0, ndir = 0;
std::string type;
utl::getAttribute(elem,"code",code);
utl::getAttribute(elem,"direction",ndir);
utl::getAttribute(elem,"type",type,true);
if (elem->FirstChild()) {
std::cout <<"\tNeumann code "<< code <<" direction "<< ndir;
if (!type.empty()) std::cout <<" ("<< type <<")";
this->setNeumann(elem->FirstChild()->Value(),type,ndir,code);
std::cout << std::endl;
}
}
else if (!strcasecmp(elem->Value(),"dirichlet") && !ignoreDirichlet) { else if (!strcasecmp(elem->Value(),"dirichlet") && !ignoreDirichlet) {
int code = 0; int code = 0;
std::string type;
utl::getAttribute(elem,"code",code); utl::getAttribute(elem,"code",code);
double val = elem->FirstChild() ? atof(elem->FirstChild()->Value()) : 0.0; utl::getAttribute(elem,"type",type,true);
if (val == 0.0) const TiXmlNode* dval = elem->FirstChild();
if (!dval || (atof(dval->Value()) == 0.0 && type != "expression")) {
setPropertyType(code,Property::DIRICHLET); setPropertyType(code,Property::DIRICHLET);
else { std::cout <<"\tDirichlet code "<< code <<": (fixed)"<< std::endl;
}
else if (dval) {
setPropertyType(code,Property::DIRICHLET_INHOM); setPropertyType(code,Property::DIRICHLET_INHOM);
std::string function; std::cout <<"\tDirichlet code "<< code;
if (utl::getAttribute(elem,"function",function)) { if (!type.empty()) std::cout <<" ("<< type <<")";
char* func = strtok(const_cast<char*>(function.c_str())," "); myScalars[code] = utl::parseRealFunc(dval->Value(),type);
myScalars[code] = const_cast<RealFunc*>(utl::parseRealFunc(func,val)); std::cout << std::endl;
}
else
myScalars[code] = new ConstFunc(val);
} }
} }
@ -261,7 +276,7 @@ bool SIMbase::parseOutputTag (const TiXmlElement* elem)
return opt.parseOutputTag(elem); return opt.parseOutputTag(elem);
const TiXmlElement* point = elem->FirstChildElement("point"); const TiXmlElement* point = elem->FirstChildElement("point");
for (int i = 1; point; i++) for (int i = 1; point; i++, point = point->NextSiblingElement())
{ {
int patch = 0; int patch = 0;
ResultPoint thePoint; ResultPoint thePoint;
@ -276,7 +291,6 @@ bool SIMbase::parseOutputTag (const TiXmlElement* elem)
if (utl::getAttribute(point,"w",thePoint.par[2]) && myPid == 0) if (utl::getAttribute(point,"w",thePoint.par[2]) && myPid == 0)
std::cout <<' '<< thePoint.par[2]; std::cout <<' '<< thePoint.par[2];
myPoints.push_back(thePoint); myPoints.push_back(thePoint);
point = point->NextSiblingElement();
} }
if (myPid == 0) if (myPid == 0)
std::cout << std::endl; std::cout << std::endl;
@ -824,6 +838,38 @@ bool SIMbase::setVecProperty (int code, Property::Type ptype, VecFunc* field)
} }
bool SIMbase::setNeumann (const std::string& prop, const std::string& type,
int direction, int code)
{
if (direction == 0 && this->getNoFields() == 1)
{
RealFunc* f = utl::parseRealFunc(prop,type);
if (f)
myScalars[code] = f;
else
return false;
}
else if (direction < 0 || this->getNoFields() == 1)
{
VecFunc* f = utl::parseVecFunc(prop,type);
if (f)
myVectors[code] = f;
else
return false;
}
else
{
TractionFunc* f = utl::parseTracFunc(prop,type,direction);
if (f)
myTracs[code] = f;
else
return false;
}
return this->setPropertyType(code,Property::NEUMANN);
}
bool SIMbase::initSystem (int mType, size_t nMats, size_t nVec) bool SIMbase::initSystem (int mType, size_t nMats, size_t nVec)
{ {
if (!mySam) return false; if (!mySam) return false;
@ -2154,7 +2200,7 @@ bool SIMbase::dumpResults (const Vector& psol, double time, std::ostream& os,
for (j = 0; j < points.size(); j++) for (j = 0; j < points.size(); j++)
{ {
if (!formatted) if (!formatted)
os << time <<" "; os << time <<" ";
else if (points[j] < 0) else if (points[j] < 0)
os <<" Point #"<< -points[j] <<":\tsol1 ="; os <<" Point #"<< -points[j] <<":\tsol1 =";
else else
@ -2168,8 +2214,8 @@ bool SIMbase::dumpResults (const Vector& psol, double time, std::ostream& os,
if (opt.discretization >= ASM::Spline) if (opt.discretization >= ASM::Spline)
{ {
if (formatted && sol2.rows() > 0) if (formatted && sol2.rows() > 0)
os <<"\n\t\tsol2 ="; os <<"\n\t\tsol2 =";
for (k = 1; k <= sol2.rows(); k++) for (k = 1; k <= sol2.rows(); k++)
os << std::setw(flWidth) << utl::trunc(sol2(k,j+1)); os << std::setw(flWidth) << utl::trunc(sol2(k,j+1));
} }
@ -2178,8 +2224,8 @@ bool SIMbase::dumpResults (const Vector& psol, double time, std::ostream& os,
// Print nodal reaction forces for nodes with prescribed DOFs // Print nodal reaction forces for nodes with prescribed DOFs
if (mySam->getNodalReactions(points[j],*reactionForces,reactionFS)) if (mySam->getNodalReactions(points[j],*reactionForces,reactionFS))
{ {
if (formatted) if (formatted)
os <<"\n\t\treac ="; os <<"\n\t\treac =";
for (k = 0; k < reactionFS.size(); k++) for (k = 0; k < reactionFS.size(); k++)
os << std::setw(flWidth) << utl::trunc(reactionFS[k]); os << std::setw(flWidth) << utl::trunc(reactionFS[k]);
} }
@ -2221,35 +2267,35 @@ bool SIMbase::project (Matrix& ssol, const Vector& psol,
switch (pMethod) { switch (pMethod) {
case SIMoptions::GLOBAL: case SIMoptions::GLOBAL:
if (msgLevel > 1 && i == 0) if (msgLevel > 1 && i == 0)
std::cout <<"\tGreville point projection"<< std::endl; std::cout <<"\tGreville point projection"<< std::endl;
if (!myModel[i]->evalSolution(values,*myProblem)) if (!myModel[i]->evalSolution(values,*myProblem))
return false; return false;
break; break;
case SIMoptions::DGL2: case SIMoptions::DGL2:
if (msgLevel > 1 && i == 0) if (msgLevel > 1 && i == 0)
std::cout <<"\tDiscrete global L2-projection"<< std::endl; std::cout <<"\tDiscrete global L2-projection"<< std::endl;
if (!myModel[i]->globalL2projection(values,*myProblem)) if (!myModel[i]->globalL2projection(values,*myProblem))
return false; return false;
break; break;
case SIMoptions::CGL2: case SIMoptions::CGL2:
if (msgLevel > 1 && i == 0) if (msgLevel > 1 && i == 0)
std::cout <<"\tContinuous global L2-projection"<< std::endl; std::cout <<"\tContinuous global L2-projection"<< std::endl;
if (!myModel[i]->globalL2projection(values,*myProblem,true)) if (!myModel[i]->globalL2projection(values,*myProblem,true))
return false; return false;
break; break;
case SIMoptions::SCR: case SIMoptions::SCR:
if (msgLevel > 1 && i == 0) if (msgLevel > 1 && i == 0)
std::cout <<"\tSuperconvergent recovery"<< std::endl; std::cout <<"\tSuperconvergent recovery"<< std::endl;
if (!myModel[i]->evalSolution(values,*myProblem,NULL,'S')) if (!myModel[i]->evalSolution(values,*myProblem,NULL,'S'))
return false; return false;
break; break;
case SIMoptions::VDSA: case SIMoptions::VDSA:
if (msgLevel > 1 && i == 0) if (msgLevel > 1 && i == 0)
std::cout <<"\tVDSA projection"<< std::endl; std::cout <<"\tVariation diminishing projection"<< std::endl;
if (!myModel[i]->evalSolution(values,*myProblem,NULL,'A')) if (!myModel[i]->evalSolution(values,*myProblem,NULL,'A'))
return false; return false;
break; break;
@ -2270,7 +2316,7 @@ bool SIMbase::project (Matrix& ssol, const Vector& psol,
default: default:
std::cerr <<" *** SIMbase::project: Projection method "<< pMethod std::cerr <<" *** SIMbase::project: Projection method "<< pMethod
<<" not implemented."<< std::endl; <<" not implemented."<< std::endl;
return false; return false;
} }

View File

@ -488,6 +488,14 @@ protected:
//! \param[in] pindex 0-based index into problem-dependent property container //! \param[in] pindex 0-based index into problem-dependent property container
bool setPropertyType(int code, Property::Type ptype, int pindex = -1); bool setPropertyType(int code, Property::Type ptype, int pindex = -1);
//! \brief Defines a Neumann boundary condition property by parsing a string.
//! \param[in] prop The string to parse the property definition from
//! \param[in] type Additional option defining the type of property definition
//! \param[in] ndir Direction of the surface traction on the Neumann boundary
//! \param[in] code The property code to be associated with this property
bool setNeumann(const std::string& prop, const std::string& type,
int ndir, int code);
//! \brief Preprocesses a user-defined Dirichlet boundary property. //! \brief Preprocesses a user-defined Dirichlet boundary property.
//! \param[in] patch 1-based index of the patch to receive the property //! \param[in] patch 1-based index of the patch to receive the property
//! \param[in] lndx Local index of the boundary item to receive the property //! \param[in] lndx Local index of the boundary item to receive the property