Added: Method to inject patch vectors using a specified madof array.

Allows to specify a basis to inject for. This will be used for mixed models
where we have DOF vectors with additional components on the first basis.

Also renamed the associated extractNodeVec method to avoid ambiguity, and
made the error handling of this method equivalent to the new inject method.
This commit is contained in:
Arne Morten Kvarving 2016-07-06 10:05:16 +02:00 committed by Knut Morten Okstad
parent 9d1c9e0c73
commit 337d0f7ebc
4 changed files with 76 additions and 11 deletions

View File

@ -970,10 +970,16 @@ void ASMbase::extractElmRes (const Matrix& globRes, Matrix& elmRes) const
}
void ASMbase::extractNodeVec (const Vector& globRes, Vector& nodeVec,
const int* madof) const
bool ASMbase::extractNodalVec (const Vector& globRes, Vector& nodeVec,
const int* madof, int ngnod) const
{
nodeVec.clear();
if (nnod == 0)
{
std::cerr <<" *** ASMbase::extractNodalVec: Empty MADOF array."<< std::endl;
return false;
}
nodeVec.reserve(nf*MLGN.size());
for (size_t i = 0; i < MLGN.size(); i++)
{
@ -981,17 +987,67 @@ void ASMbase::extractNodeVec (const Vector& globRes, Vector& nodeVec,
int idof = madof[inod-1] - 1;
int jdof = madof[inod] - 1;
#ifdef INDEX_CHECK
if (inod < 1 || jdof > (int)globRes.size())
std::cerr <<" *** ASMbase::extractNodeVec: Global DOF "<< jdof
bool ok = false;
if (inod < 1 || (inod > ngnod && ngnod > 0))
std::cerr <<" *** ASMbase::extractNodalVec: Global node "<< inod
<<" is out of range [1,"<< std::abs(ngnod) <<"]."<< std::endl;
else if (jdof > (int)globRes.size())
std::cerr <<" *** ASMbase::extractNodalVec: Global DOF "<< jdof
<<" is out of range [1,"<< globRes.size() <<"]."<< std::endl;
else
ok = true;
if (!ok) continue;
#endif
nodeVec.insert(nodeVec.end(),globRes.ptr()+idof,globRes.ptr()+jdof);
}
return true;
}
bool ASMbase::injectNodalVec (const Vector& nodeVec, Vector& globVec,
const std::vector<int>& madof, int basis) const
{
if (madof.empty())
{
std::cerr <<" *** ASMbase::injectNodalVec: Empty MADOF array."<< std::endl;
return false;
}
size_t ldof = 0;
char bType = basis == 1 ? 'D' : 'P'+basis-2;
for (size_t i = 0; i < MLGN.size(); i++)
if (basis == 0 || this->getNodeType(i+1) == bType)
{
int inod = MLGN[i];
int idof = madof[inod-1] - 1;
int ndof = madof[inod] - 1 - idof;
#ifdef INDEX_CHECK
bool ok = false;
if (inod < 1 || inod > (int)madof.size())
std::cerr <<" *** ASMbase::injectNodalVec: Node "<< inod
<<" is out of range [1,"<< madof.size() <<"]."<< std::endl;
else if (ldof+ndof > nodeVec.size())
std::cerr <<" *** ASMbase::injectNodalVec: Local DOF "<< ldof+ndof
<<" is out of range [1,"<< nodeVec.size() <<"]"<< std::endl;
else if (idof+ndof > (int)globVec.size())
std::cerr <<" *** ASMbase::injectNodalVec: Global DOF "<< idof+ndof
<<" is out of range [1,"<< globVec.size() <<"]"<< std::endl;
else
ok = true;
if (!ok) continue;
#endif
std::copy(nodeVec.begin()+ldof, nodeVec.begin()+ldof+ndof,
globVec.begin()+idof);
ldof += ndof;
}
return true;
}
void ASMbase::extractNodeVec (const Vector& globRes, Vector& nodeVec,
unsigned char nndof, int basis) const
unsigned char nndof, int basis) const
{
if (nndof == 0) nndof = nf;
@ -1019,7 +1075,7 @@ void ASMbase::extractNodeVec (const Vector& globRes, Vector& nodeVec,
bool ASMbase::injectNodeVec (const Vector& nodeVec, Vector& globRes,
unsigned char nndof, int) const
unsigned char nndof, int) const
{
if (nndof == 0) nndof = nf;

View File

@ -541,8 +541,9 @@ public:
//! \param[in] globVec Global solution vector in DOF-order
//! \param[out] nodeVec Nodal result vector for this patch
//! \param[in] madof Global Matrix of Accumulated DOFs
void extractNodeVec(const Vector& globVec, Vector& nodeVec,
const int* madof) const;
//! \param[in] ngnod Dimension of madof (the default -1 means unknown)
bool extractNodalVec(const Vector& globVec, Vector& nodeVec,
const int* madof, int ngnod = -1) const;
//! \brief Extracts nodal results for this patch from the global vector.
//! \param[in] globVec Global solution vector in DOF-order
@ -560,6 +561,14 @@ public:
virtual bool injectNodeVec(const Vector& nodeVec, Vector& globVec,
unsigned char nndof = 0, int basis = 0) const;
//! \brief Injects nodal results for this patch into the global vector.
//! \param[in] nodeVec Nodal result vector for this patch
//! \param globVec Global solution vector in DOF-order
//! \param[in] madof Global Matrix of Accumulated DOFs
//! \param[in] basis Which basis to inject nodal values for (mixed methods)
bool injectNodalVec(const Vector& nodeVec, Vector& globVec,
const std::vector<int>& madof, int basis = 0) const;
//! \brief Creates and adds a two-point constraint to this patch.
//! \param[in] slave Global node number of the node to constrain
//! \param[in] dir Which local DOF to constrain (1, 2, 3)

View File

@ -2502,7 +2502,7 @@ bool SIMbase::extractPatchSolution (IntegrandBase* problem,
problem->initNodeMap(pch->getGlobalNodeNums());
for (size_t i = 0; i < sol.size() && i < problem->getNoSolutions(); i++)
if (!sol[i].empty())
pch->extractNodeVec(sol[i],problem->getSolution(i),mySam->getMADOF());
pch->extractNodalVec(sol[i],problem->getSolution(i),mySam->getMADOF());
return this->extractPatchDependencies(problem,myModel,pindx);
}

View File

@ -1097,7 +1097,7 @@ void SIMoutput::dumpPrimSol (const Vector& psol, utl::LogStream& os,
if (myModel[i]->empty()) continue; // skip empty patches
Vector patchSol;
myModel[i]->extractNodeVec(psol,patchSol,mySam->getMADOF());
myModel[i]->extractNodalVec(psol,patchSol,mySam->getMADOF());
if (withID)
{
@ -1141,7 +1141,7 @@ bool SIMoutput::dumpSolution (const Vector& psol, utl::LogStream& os) const
// Extract and write primary solution
size_t nf = myModel[i]->getNoFields(1);
Vector& patchSol = myProblem->getSolution();
myModel[i]->extractNodeVec(psol,patchSol,mySam->getMADOF());
myModel[i]->extractNodalVec(psol,patchSol,mySam->getMADOF());
for (k = 0; k < nf; k++)
{
os << myProblem->getField1Name(k,"# FE");