Added evaluation for solution at user-defined points
git-svn-id: http://svn.sintef.no/trondheim/IFEM/trunk@900 e10b68d5-8a6e-419e-a041-bce267b0401d
This commit is contained in:
parent
133153e045
commit
a5eaefef22
@ -22,10 +22,8 @@
|
|||||||
|
|
||||||
|
|
||||||
NonlinearElasticityUL::NonlinearElasticityUL (unsigned short int n, char lop)
|
NonlinearElasticityUL::NonlinearElasticityUL (unsigned short int n, char lop)
|
||||||
: Elasticity(n)
|
: Elasticity(n), loadOp(lop), plam(-999.9)
|
||||||
{
|
{
|
||||||
loadOp = lop;
|
|
||||||
|
|
||||||
// Only the current solution is needed
|
// Only the current solution is needed
|
||||||
primsol.resize(1);
|
primsol.resize(1);
|
||||||
}
|
}
|
||||||
@ -94,10 +92,13 @@ void NonlinearElasticityUL::initIntegration (const TimeDomain& prm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void NonlinearElasticityUL::initResultPoints ()
|
void NonlinearElasticityUL::initResultPoints (double lambda)
|
||||||
{
|
{
|
||||||
if (material)
|
if (material && lambda > plam)
|
||||||
|
{
|
||||||
material->initResultPoints();
|
material->initResultPoints();
|
||||||
|
plam = lambda;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,7 +47,8 @@ public:
|
|||||||
//! \param[in] prm Nonlinear solution algorithm parameters
|
//! \param[in] prm Nonlinear solution algorithm parameters
|
||||||
virtual void initIntegration(const TimeDomain& prm);
|
virtual void initIntegration(const TimeDomain& prm);
|
||||||
//! \brief Initializes the integrand for a result point loop.
|
//! \brief Initializes the integrand for a result point loop.
|
||||||
virtual void initResultPoints();
|
//! \param[in] lambda Load parameter
|
||||||
|
virtual void initResultPoints(double lambda);
|
||||||
|
|
||||||
//! \brief Evaluates the integrand at an interior point.
|
//! \brief Evaluates the integrand at an interior point.
|
||||||
//! \param elmInt The local integral object to receive the contributions
|
//! \param elmInt The local integral object to receive the contributions
|
||||||
@ -94,6 +95,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
char loadOp; //!< Load option
|
char loadOp; //!< Load option
|
||||||
|
double plam; //!< Load parameter of the previous result evaluation
|
||||||
|
|
||||||
friend class ElasticityNormUL;
|
friend class ElasticityNormUL;
|
||||||
};
|
};
|
||||||
|
@ -104,12 +104,14 @@ void PlasticMaterial::initIntegration (const TimeDomain& prm)
|
|||||||
|
|
||||||
if (prm.it > 0 || prm.first) return;
|
if (prm.it > 0 || prm.first) return;
|
||||||
|
|
||||||
|
int nUpdated = 0;
|
||||||
for (size_t i = 0; i < itgPoints.size(); i++)
|
for (size_t i = 0; i < itgPoints.size(); i++)
|
||||||
itgPoints[i]->updateHistoryVars();
|
if (itgPoints[i]->updateHistoryVars())
|
||||||
|
nUpdated++;
|
||||||
|
|
||||||
#if INT_DEBUG > 0
|
#if INT_DEBUG > 0
|
||||||
std::cout <<"PlasticMaterial::initIntegration: History updated "
|
std::cout <<"PlasticMaterial::initIntegration: History updated "
|
||||||
<< itgPoints.size() << std::endl;
|
<< nUpdated << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,12 +125,14 @@ void PlasticMaterial::initResultPoints ()
|
|||||||
iP2 = 0;
|
iP2 = 0;
|
||||||
iAmIntegrating = false;
|
iAmIntegrating = false;
|
||||||
|
|
||||||
|
int nUpdated = 0;
|
||||||
for (size_t i = 0; i < resPoints.size(); i++)
|
for (size_t i = 0; i < resPoints.size(); i++)
|
||||||
resPoints[i]->updateHistoryVars();
|
if (resPoints[i]->updateHistoryVars())
|
||||||
|
nUpdated++;
|
||||||
|
|
||||||
#if INT_DEBUG > 0
|
#if INT_DEBUG > 0
|
||||||
std::cout <<"PlasticMaterial::initResultPoints: History updated "
|
std::cout <<"PlasticMaterial::initResultPoints: History updated "
|
||||||
<< resPoints.size() << std::endl;
|
<< nUpdated << std::endl;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +174,7 @@ bool PlasticMaterial::evaluate (Matrix& C, SymmTensor& sigma, double&,
|
|||||||
|
|
||||||
PlasticMaterial::PlasticPoint::PlasticPoint (const PlasticMaterial* prm,
|
PlasticMaterial::PlasticPoint::PlasticPoint (const PlasticMaterial* prm,
|
||||||
unsigned short int n)
|
unsigned short int n)
|
||||||
: pMAT(prm->pMAT), Fp(n)
|
: pMAT(prm->pMAT), updated(false), Fp(n)
|
||||||
{
|
{
|
||||||
// Initialize the history variables
|
// Initialize the history variables
|
||||||
memset(HVc,0,sizeof(HVc));
|
memset(HVc,0,sizeof(HVc));
|
||||||
@ -179,10 +183,15 @@ PlasticMaterial::PlasticPoint::PlasticPoint (const PlasticMaterial* prm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PlasticMaterial::PlasticPoint::updateHistoryVars ()
|
bool PlasticMaterial::PlasticPoint::updateHistoryVars ()
|
||||||
{
|
{
|
||||||
|
if (!updated) return false;
|
||||||
|
|
||||||
// Update history variables with values of the new converged solution
|
// Update history variables with values of the new converged solution
|
||||||
memcpy(HVp,HVc,sizeof(HVc));
|
memcpy(HVp,HVc,sizeof(HVc));
|
||||||
|
updated = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -209,6 +218,12 @@ bool PlasticMaterial::PlasticPoint::evaluate (Matrix& C,
|
|||||||
int ierr = -99;
|
int ierr = -99;
|
||||||
#ifdef USE_FTNMAT
|
#ifdef USE_FTNMAT
|
||||||
// Invoke the FORTRAN routine for plasticity material models
|
// Invoke the FORTRAN routine for plasticity material models
|
||||||
|
#if INT_DEBUG > 0
|
||||||
|
std::cout <<"PlasticMaterial::Fp =\n"<< Fp;
|
||||||
|
std::cout <<"PlasticMaterial::HV =";
|
||||||
|
for (int i = 0; i < 10; i++) std::cout <<" "<< HVc[i];
|
||||||
|
std::cout << std::endl;
|
||||||
|
#endif
|
||||||
if (ndim == 2)
|
if (ndim == 2)
|
||||||
plas2d_(INT_DEBUG,6,prm.it,prm.first,4,&pMAT.front(),J,F.dim(),
|
plas2d_(INT_DEBUG,6,prm.it,prm.first,4,&pMAT.front(),J,F.dim(),
|
||||||
F.ptr(),Fp.ptr(),HVc,HVc[6],HVc+7,sigma.ptr(),C.ptr(),ierr);
|
F.ptr(),Fp.ptr(),HVc,HVc[6],HVc+7,sigma.ptr(),C.ptr(),ierr);
|
||||||
@ -223,5 +238,6 @@ bool PlasticMaterial::PlasticPoint::evaluate (Matrix& C,
|
|||||||
std::cerr <<" *** PlasticMaterial::evaluate: Not included."<< std::endl;
|
std::cerr <<" *** PlasticMaterial::evaluate: Not included."<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const_cast<PlasticPoint*>(this)->updated = true;
|
||||||
return ierr == 0;
|
return ierr == 0;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class PlasticMaterial : public Material
|
|||||||
PlasticPoint(const PlasticMaterial* prm, unsigned short int n);
|
PlasticPoint(const PlasticMaterial* prm, unsigned short int n);
|
||||||
|
|
||||||
//! \brief Updates the internal history variables after convergence.
|
//! \brief Updates the internal history variables after convergence.
|
||||||
void updateHistoryVars();
|
bool updateHistoryVars();
|
||||||
|
|
||||||
//! \brief Evaluates the constitutive relation at this point.
|
//! \brief Evaluates the constitutive relation at this point.
|
||||||
//! \param[out] C Constitutive matrix at current point
|
//! \param[out] C Constitutive matrix at current point
|
||||||
@ -67,6 +67,7 @@ class PlasticMaterial : public Material
|
|||||||
|
|
||||||
double HVc[10]; //!< History variables, current configuration
|
double HVc[10]; //!< History variables, current configuration
|
||||||
double HVp[10]; //!< History variables, previous configuration
|
double HVp[10]; //!< History variables, previous configuration
|
||||||
|
bool updated; //!< Flag indicating whether history variables are updated
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Tensor Fp; //!< Deformation gradient, previous configuration
|
Tensor Fp; //!< Deformation gradient, previous configuration
|
||||||
|
@ -76,7 +76,7 @@ int main (int argc, char** argv)
|
|||||||
bool twoD = false;
|
bool twoD = false;
|
||||||
char* infile = 0;
|
char* infile = 0;
|
||||||
|
|
||||||
LinAlgInit linalg(argc,argv);
|
const LinAlgInit& linalg = LinAlgInit::Init(argc,argv);
|
||||||
|
|
||||||
std::vector<int> options(2,0);
|
std::vector<int> options(2,0);
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
@ -294,6 +294,9 @@ int main (int argc, char** argv)
|
|||||||
if (!simulator.solveStep(params,SIM::STATIC))
|
if (!simulator.solveStep(params,SIM::STATIC))
|
||||||
return 5;
|
return 5;
|
||||||
|
|
||||||
|
// Print solution components at the user-defined points
|
||||||
|
simulator.dumpResults(params.time.t,std::cout);
|
||||||
|
|
||||||
if (params.time.t + epsT*params.time.dt > nextDump)
|
if (params.time.t + epsT*params.time.dt > nextDump)
|
||||||
{
|
{
|
||||||
// Dump primary solution for inspection or external processing
|
// Dump primary solution for inspection or external processing
|
||||||
|
@ -47,7 +47,7 @@ typedef std::vector<ASMbase*> ASMVec; //!< Spline patch container
|
|||||||
of a set of partial differential equations using splines as basis functions.
|
of a set of partial differential equations using splines as basis functions.
|
||||||
|
|
||||||
The class does not contain any problem-specific data or methods.
|
The class does not contain any problem-specific data or methods.
|
||||||
The methods that need access to problem information are provided that through
|
The methods that need access to problem information are given that through
|
||||||
Integrand objects that are passed as arguments to those methods.
|
Integrand objects that are passed as arguments to those methods.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -225,6 +225,12 @@ public:
|
|||||||
// Post-processing methods
|
// Post-processing methods
|
||||||
// =======================
|
// =======================
|
||||||
|
|
||||||
|
//! \brief Evaluates the geometry at a specified point.
|
||||||
|
//! \param[in] xi Dimensionless parameters in range [0.0,1.0] of the point
|
||||||
|
//! \param[out] param The parameters of the point in the knot-span domain
|
||||||
|
//! \param[out] X The Cartesian coordinates of the point
|
||||||
|
virtual bool evalPoint(const double* xi, double* param, Vec3& X) const = 0;
|
||||||
|
|
||||||
//! \brief Creates a standard FE model of this patch for visualization.
|
//! \brief Creates a standard FE model of this patch for visualization.
|
||||||
//! \param[out] grid The generated finite element grid
|
//! \param[out] grid The generated finite element grid
|
||||||
//! \param[in] npe Number of visualization nodes over each knot span
|
//! \param[in] npe Number of visualization nodes over each knot span
|
||||||
@ -295,7 +301,7 @@ public:
|
|||||||
virtual void extractNodeVec(const Vector& globVec, Vector& nodeVec,
|
virtual void extractNodeVec(const Vector& globVec, Vector& nodeVec,
|
||||||
unsigned char nndof = 0) const;
|
unsigned char nndof = 0) const;
|
||||||
|
|
||||||
//! \brief Inject nodal results for this patch into the global vector.
|
//! \brief Injects nodal results for this patch into the global vector.
|
||||||
//! \param[in] nodeVec Nodal result vector for this patch
|
//! \param[in] nodeVec Nodal result vector for this patch
|
||||||
//! \param globVec Global solution vector in DOF-order
|
//! \param globVec Global solution vector in DOF-order
|
||||||
//! \param[in] nndof Number of DOFs per node (the default is \a nf)
|
//! \param[in] nndof Number of DOFs per node (the default is \a nf)
|
||||||
|
@ -29,10 +29,8 @@
|
|||||||
|
|
||||||
|
|
||||||
ASMs1D::ASMs1D (const char* fileName, unsigned char n_s, unsigned char n_f)
|
ASMs1D::ASMs1D (const char* fileName, unsigned char n_s, unsigned char n_f)
|
||||||
: ASMstruct(1,n_s,n_f)
|
: ASMstruct(1,n_s,n_f), curv(0)
|
||||||
{
|
{
|
||||||
curv = 0;
|
|
||||||
|
|
||||||
std::cout <<"\nReading patch file "<< fileName << std::endl;
|
std::cout <<"\nReading patch file "<< fileName << std::endl;
|
||||||
std::ifstream is(fileName);
|
std::ifstream is(fileName);
|
||||||
if (!is.good())
|
if (!is.good())
|
||||||
@ -45,10 +43,8 @@ ASMs1D::ASMs1D (const char* fileName, unsigned char n_s, unsigned char n_f)
|
|||||||
|
|
||||||
|
|
||||||
ASMs1D::ASMs1D (std::istream& is, unsigned char n_s, unsigned char n_f)
|
ASMs1D::ASMs1D (std::istream& is, unsigned char n_s, unsigned char n_f)
|
||||||
: ASMstruct(1,n_s,n_f)
|
: ASMstruct(1,n_s,n_f), curv(0)
|
||||||
{
|
{
|
||||||
curv = 0;
|
|
||||||
|
|
||||||
this->read(is);
|
this->read(is);
|
||||||
|
|
||||||
geo = curv;
|
geo = curv;
|
||||||
@ -56,9 +52,8 @@ ASMs1D::ASMs1D (std::istream& is, unsigned char n_s, unsigned char n_f)
|
|||||||
|
|
||||||
|
|
||||||
ASMs1D::ASMs1D (unsigned char n_s, unsigned char n_f)
|
ASMs1D::ASMs1D (unsigned char n_s, unsigned char n_f)
|
||||||
: ASMstruct(1,n_s,n_f)
|
: ASMstruct(1,n_s,n_f), curv(0)
|
||||||
{
|
{
|
||||||
curv = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -608,6 +603,21 @@ bool ASMs1D::integrate (Integrand& integrand, int lIndex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ASMs1D::evalPoint (const double* xi, double* param, Vec3& X) const
|
||||||
|
{
|
||||||
|
if (!curv) return false;
|
||||||
|
|
||||||
|
param[0] = (1.0-xi[0])*curv->startparam() + xi[0]*curv->endparam();
|
||||||
|
|
||||||
|
Go::Point X0;
|
||||||
|
curv->point(X0,param[0]);
|
||||||
|
for (unsigned char i = 0; i < nsd; i++)
|
||||||
|
X[i] = X0[i];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ASMs1D::getGridParameters (RealArray& prm, int nSegPerSpan) const
|
bool ASMs1D::getGridParameters (RealArray& prm, int nSegPerSpan) const
|
||||||
{
|
{
|
||||||
if (!curv) return false;
|
if (!curv) return false;
|
||||||
@ -772,6 +782,8 @@ Go::GeomObject* ASMs1D::evalSolution (const Integrand& integrand) const
|
|||||||
|
|
||||||
Go::SplineCurve* ASMs1D::projectSolution (const Integrand& integrand) const
|
Go::SplineCurve* ASMs1D::projectSolution (const Integrand& integrand) const
|
||||||
{
|
{
|
||||||
|
//TODO: This requires the method Go::CurveInterpolator::regularInterpolation
|
||||||
|
// which is not yet present in GoTools.
|
||||||
std::cerr <<"ASMs1D::projectSolution: Not implemented yet!"<< std::endl;
|
std::cerr <<"ASMs1D::projectSolution: Not implemented yet!"<< std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -122,6 +122,12 @@ public:
|
|||||||
// Post-processing methods
|
// Post-processing methods
|
||||||
// =======================
|
// =======================
|
||||||
|
|
||||||
|
//! \brief Evaluates the geometry at a specified point.
|
||||||
|
//! \param[in] xi Dimensionless parameter in range [0.0,1.0] of the point
|
||||||
|
//! \param[out] param The parameter of the point in the knot-span domain
|
||||||
|
//! \param[out] X The Cartesian coordinates of the point
|
||||||
|
virtual bool evalPoint(const double* xi, double* param, Vec3& X) const;
|
||||||
|
|
||||||
//! \brief Creates a line element model of this patch for visualization.
|
//! \brief Creates a line element model of this patch for visualization.
|
||||||
//! \param[out] grid The generated line grid
|
//! \param[out] grid The generated line grid
|
||||||
//! \param[in] npe Number of visualization nodes over each knot span
|
//! \param[in] npe Number of visualization nodes over each knot span
|
||||||
|
@ -31,10 +31,8 @@
|
|||||||
|
|
||||||
|
|
||||||
ASMs2D::ASMs2D (const char* fileName, unsigned char n_s, unsigned char n_f)
|
ASMs2D::ASMs2D (const char* fileName, unsigned char n_s, unsigned char n_f)
|
||||||
: ASMstruct(2,n_s,n_f)
|
: ASMstruct(2,n_s,n_f), surf(0)
|
||||||
{
|
{
|
||||||
surf = 0;
|
|
||||||
|
|
||||||
std::cout <<"\nReading patch file "<< fileName << std::endl;
|
std::cout <<"\nReading patch file "<< fileName << std::endl;
|
||||||
std::ifstream is(fileName);
|
std::ifstream is(fileName);
|
||||||
if (!is.good())
|
if (!is.good())
|
||||||
@ -47,10 +45,8 @@ ASMs2D::ASMs2D (const char* fileName, unsigned char n_s, unsigned char n_f)
|
|||||||
|
|
||||||
|
|
||||||
ASMs2D::ASMs2D (std::istream& is, unsigned char n_s, unsigned char n_f)
|
ASMs2D::ASMs2D (std::istream& is, unsigned char n_s, unsigned char n_f)
|
||||||
: ASMstruct(2,n_s,n_f)
|
: ASMstruct(2,n_s,n_f), surf(0)
|
||||||
{
|
{
|
||||||
surf = 0;
|
|
||||||
|
|
||||||
this->read(is);
|
this->read(is);
|
||||||
|
|
||||||
geo = surf;
|
geo = surf;
|
||||||
@ -58,9 +54,8 @@ ASMs2D::ASMs2D (std::istream& is, unsigned char n_s, unsigned char n_f)
|
|||||||
|
|
||||||
|
|
||||||
ASMs2D::ASMs2D (unsigned char n_s, unsigned char n_f)
|
ASMs2D::ASMs2D (unsigned char n_s, unsigned char n_f)
|
||||||
: ASMstruct(2,n_s,n_f)
|
: ASMstruct(2,n_s,n_f), surf(0)
|
||||||
{
|
{
|
||||||
surf = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -659,7 +654,7 @@ Vec3 ASMs2D::getCoord (size_t inod) const
|
|||||||
if (ip < 0) return X;
|
if (ip < 0) return X;
|
||||||
|
|
||||||
RealArray::const_iterator cit = surf->coefs_begin() + ip;
|
RealArray::const_iterator cit = surf->coefs_begin() + ip;
|
||||||
for (size_t i = 0; i < nsd; i++, cit++)
|
for (unsigned char i = 0; i < nsd; i++, cit++)
|
||||||
X[i] = *cit;
|
X[i] = *cit;
|
||||||
|
|
||||||
return X;
|
return X;
|
||||||
@ -753,7 +748,7 @@ void ASMs2D::extractBasis (const Go::BasisDerivsSf2& spline,
|
|||||||
|
|
||||||
|
|
||||||
#if SP_DEBUG > 4
|
#if SP_DEBUG > 4
|
||||||
std::ostream& operator<<(std::ostream& os, const Go::BasisDerivsSf& bder)
|
std::ostream& operator<< (std::ostream& os, const Go::BasisDerivsSf& bder)
|
||||||
{
|
{
|
||||||
os <<" : (u,v) = "<< bder.param[0] <<" "<< bder.param[1]
|
os <<" : (u,v) = "<< bder.param[0] <<" "<< bder.param[1]
|
||||||
<<" left_idx = "<< bder.left_idx[0] <<" "<< bder.left_idx[1] << std::endl;
|
<<" left_idx = "<< bder.left_idx[0] <<" "<< bder.left_idx[1] << std::endl;
|
||||||
@ -876,8 +871,8 @@ bool ASMs2D::integrate (Integrand& integrand,
|
|||||||
double u0 = 0.5*(gpar[0](1,i1-p1+1) + gpar[0](nGauss,i1-p1+1));
|
double u0 = 0.5*(gpar[0](1,i1-p1+1) + gpar[0](nGauss,i1-p1+1));
|
||||||
double v0 = 0.5*(gpar[1](1,i2-p2+1) + gpar[1](nGauss,i2-p2+1));
|
double v0 = 0.5*(gpar[1](1,i2-p2+1) + gpar[1](nGauss,i2-p2+1));
|
||||||
surf->point(X0,u0,v0);
|
surf->point(X0,u0,v0);
|
||||||
X.x = X0[0];
|
for (unsigned char i = 0; i < nsd; i++)
|
||||||
X.y = X0[1];
|
X[i] = X0[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize element quantities
|
// Initialize element quantities
|
||||||
@ -1083,6 +1078,23 @@ bool ASMs2D::integrate (Integrand& integrand, int lIndex,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ASMs2D::evalPoint (const double* xi, double* param, Vec3& X) const
|
||||||
|
{
|
||||||
|
if (!surf) return false;
|
||||||
|
|
||||||
|
param[0] = (1.0-xi[0])*surf->startparam_u() + xi[0]*surf->endparam_u();
|
||||||
|
param[1] = (1.0-xi[1])*surf->startparam_v() + xi[1]*surf->endparam_v();
|
||||||
|
|
||||||
|
Go::Point X0;
|
||||||
|
surf->point(X0,param[0],param[1]);
|
||||||
|
for (unsigned char i = 0; i < nsd; i++)
|
||||||
|
X[i] = X0[i];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool ASMs2D::getGridParameters (RealArray& prm, int dir, int nSegPerSpan) const
|
bool ASMs2D::getGridParameters (RealArray& prm, int dir, int nSegPerSpan) const
|
||||||
{
|
{
|
||||||
if (!surf) return false;
|
if (!surf) return false;
|
||||||
|
@ -195,6 +195,12 @@ public:
|
|||||||
// Post-processing methods
|
// Post-processing methods
|
||||||
// =======================
|
// =======================
|
||||||
|
|
||||||
|
//! \brief Evaluates the geometry at a specified point.
|
||||||
|
//! \param[in] xi Dimensionless parameters in range [0.0,1.0] of the point
|
||||||
|
//! \param[out] param The (u,v) parameters of the point in knot-span domain
|
||||||
|
//! \param[out] X The Cartesian coordinates of the point
|
||||||
|
virtual bool evalPoint(const double* xi, double* param, Vec3& X) const;
|
||||||
|
|
||||||
//! \brief Creates a quad element model of this patch for visualization.
|
//! \brief Creates a quad element model of this patch for visualization.
|
||||||
//! \param[out] grid The generated quadrilateral grid
|
//! \param[out] grid The generated quadrilateral grid
|
||||||
//! \param[in] npe Number of visualization nodes over each knot span
|
//! \param[in] npe Number of visualization nodes over each knot span
|
||||||
|
@ -31,11 +31,8 @@
|
|||||||
|
|
||||||
|
|
||||||
ASMs3D::ASMs3D (const char* fileName, bool checkRHS, unsigned char n_f)
|
ASMs3D::ASMs3D (const char* fileName, bool checkRHS, unsigned char n_f)
|
||||||
: ASMstruct(3,3,n_f)
|
: ASMstruct(3,3,n_f), svol(0), swapW(false)
|
||||||
{
|
{
|
||||||
svol = 0;
|
|
||||||
swapW = false;
|
|
||||||
|
|
||||||
std::cout <<"\nReading patch file "<< fileName << std::endl;
|
std::cout <<"\nReading patch file "<< fileName << std::endl;
|
||||||
std::ifstream is(fileName);
|
std::ifstream is(fileName);
|
||||||
if (!is.good())
|
if (!is.good())
|
||||||
@ -48,11 +45,8 @@ ASMs3D::ASMs3D (const char* fileName, bool checkRHS, unsigned char n_f)
|
|||||||
|
|
||||||
|
|
||||||
ASMs3D::ASMs3D (std::istream& is, bool checkRHS, unsigned char n_f)
|
ASMs3D::ASMs3D (std::istream& is, bool checkRHS, unsigned char n_f)
|
||||||
: ASMstruct(3,3,n_f)
|
: ASMstruct(3,3,n_f), svol(0), swapW(false)
|
||||||
{
|
{
|
||||||
svol = 0;
|
|
||||||
swapW = false;
|
|
||||||
|
|
||||||
if (this->read(is) && checkRHS)
|
if (this->read(is) && checkRHS)
|
||||||
this->checkRightHandSystem();
|
this->checkRightHandSystem();
|
||||||
|
|
||||||
@ -1599,6 +1593,23 @@ bool ASMs3D::integrateEdge (Integrand& integrand, int lEdge,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ASMs3D::evalPoint (const double* xi, double* param, Vec3& X) const
|
||||||
|
{
|
||||||
|
if (!svol) return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
param[i] = (1.0-xi[i])*svol->startparam(i) + xi[i]*svol->endparam(i);
|
||||||
|
|
||||||
|
Go::Point X0;
|
||||||
|
svol->point(X0,param[0],param[1],param[2]);
|
||||||
|
X.x = X0[0];
|
||||||
|
X.y = X0[1];
|
||||||
|
X.z = X0[2];
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ASMs3D::getGridParameters (RealArray& prm, int dir, int nSegPerSpan) const
|
bool ASMs3D::getGridParameters (RealArray& prm, int dir, int nSegPerSpan) const
|
||||||
{
|
{
|
||||||
if (!svol) return false;
|
if (!svol) return false;
|
||||||
|
@ -90,7 +90,7 @@ public:
|
|||||||
//! \brief Constructor creating an instance by reading the given input stream.
|
//! \brief Constructor creating an instance by reading the given input stream.
|
||||||
ASMs3D(std::istream& is, bool checkRHS = false, unsigned char n_f = 3);
|
ASMs3D(std::istream& is, bool checkRHS = false, unsigned char n_f = 3);
|
||||||
//! \brief Default constructor creating an empty patch.
|
//! \brief Default constructor creating an empty patch.
|
||||||
ASMs3D(unsigned char n_f = 3) : ASMstruct(3,3,n_f) { svol = 0; }
|
ASMs3D(unsigned char n_f = 3) : ASMstruct(3,3,n_f), svol(0), swapW(false) {}
|
||||||
//! \brief Empty destructor.
|
//! \brief Empty destructor.
|
||||||
virtual ~ASMs3D() {}
|
virtual ~ASMs3D() {}
|
||||||
|
|
||||||
@ -260,6 +260,12 @@ public:
|
|||||||
// Post-processing methods
|
// Post-processing methods
|
||||||
// =======================
|
// =======================
|
||||||
|
|
||||||
|
//! \brief Evaluates the geometry at a specified point.
|
||||||
|
//! \param[in] xi Dimensionless parameters in range [0.0,1.0] of the point
|
||||||
|
//! \param[out] param The (u,v,w) parameters of the point in knot-span domain
|
||||||
|
//! \param[out] X The Cartesian coordinates of the point
|
||||||
|
virtual bool evalPoint(const double* xi, double* param, Vec3& X) const;
|
||||||
|
|
||||||
//! \brief Creates a hexahedron element model of this patch for visualization.
|
//! \brief Creates a hexahedron element model of this patch for visualization.
|
||||||
//! \param[out] grid The generated hexahedron grid
|
//! \param[out] grid The generated hexahedron grid
|
||||||
//! \param[in] npe Number of visualization nodes over each knot span
|
//! \param[in] npe Number of visualization nodes over each knot span
|
||||||
|
@ -30,15 +30,17 @@ class VTF;
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Abstract base class representing a system level integrated quantity.
|
\brief Abstract base class representing a system level integrated quantity.
|
||||||
\details This class defines the interface between the finite element
|
\details This class defines the interface between the finite element (FE)
|
||||||
assembly drivers of the ASM-hierarchy and the problem-dependent classes
|
assembly drivers of the ASM-hierarchy and the problem-dependent classes
|
||||||
containing all physical properties for the problem to be solved.
|
containing all physical properties for the problem to be solved.
|
||||||
|
|
||||||
The interface has several overloaded versions of the \a evalInt method, for
|
The interface consists of methods for evaluating the integrand at interior
|
||||||
evaluation of the coefficient matrix contributions at an element-interior
|
integration points (\a evalInt), and at boundary integration points
|
||||||
integration point. Only one of these methods needs to be implemented, and
|
(\a evalBou). The latter are used for Neumann boundary conditions, typically.
|
||||||
which one to use is governed by the \a getIntegrandType method.
|
The integrand evaluation methods have access to the FE basis function values
|
||||||
There is also one method intended for mixed field interpolation problems.
|
and derivatives through the FiniteElement argument. There are also a set
|
||||||
|
of methods dedicated for mixed field interpolation problems, which take
|
||||||
|
and MxFiniteElement object as argument instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Integrand
|
class Integrand
|
||||||
@ -51,18 +53,28 @@ public:
|
|||||||
//! \brief Empty destructor.
|
//! \brief Empty destructor.
|
||||||
virtual ~Integrand() {}
|
virtual ~Integrand() {}
|
||||||
|
|
||||||
//! \brief Prints out problem definition to the given output stream.
|
//! \brief Prints out the problem definition to the given output stream.
|
||||||
virtual void print(std::ostream&) const {}
|
virtual void print(std::ostream&) const {}
|
||||||
|
|
||||||
|
|
||||||
|
// Global initialization interface
|
||||||
|
// ===============================
|
||||||
|
|
||||||
//! \brief Defines the solution mode before the element assembly is started.
|
//! \brief Defines the solution mode before the element assembly is started.
|
||||||
virtual void setMode(SIM::SolutionMode) {}
|
virtual void setMode(SIM::SolutionMode) {}
|
||||||
|
|
||||||
//! \brief Initializes the integrand for a new integration loop.
|
//! \brief Initializes the integrand for a new integration loop.
|
||||||
//! \details This method is invoked once before starting the numerical
|
//! \details This method is invoked once before starting the numerical
|
||||||
//! integration over the entire spatial domain.
|
//! integration over the entire spatial domain.
|
||||||
virtual void initIntegration(const TimeDomain&) {}
|
virtual void initIntegration(const TimeDomain&) {}
|
||||||
//! \brief Initializes the integrand for a new result point loop.
|
//! \brief Initializes the integrand for a new result point loop.
|
||||||
virtual void initResultPoints() {}
|
//! \details This method is invoked once before starting the evaluation of
|
||||||
|
//! the secondary solution at all result sampling points, after the converged
|
||||||
|
//! primary solution has been found.
|
||||||
|
virtual void initResultPoints(double) {}
|
||||||
|
|
||||||
|
|
||||||
|
// Element-level initialization interface
|
||||||
|
// ======================================
|
||||||
|
|
||||||
//! \brief Initializes current element for numerical integration.
|
//! \brief Initializes current element for numerical integration.
|
||||||
//! \param[in] MNPC Matrix of nodal point correspondance for current element
|
//! \param[in] MNPC Matrix of nodal point correspondance for current element
|
||||||
@ -85,7 +97,7 @@ public:
|
|||||||
//! \brief Initializes current element for numerical integration.
|
//! \brief Initializes current element for numerical integration.
|
||||||
//! \param[in] MNPC Matrix of nodal point correspondance for current element
|
//! \param[in] MNPC Matrix of nodal point correspondance for current element
|
||||||
//!
|
//!
|
||||||
//! \details Reimplement this method for problems not requiring the
|
//! \details Reimplement this method for problems \e not requiring the
|
||||||
//! the element center nor the number of integration points before the
|
//! the element center nor the number of integration points before the
|
||||||
//! integration loop is started.
|
//! integration loop is started.
|
||||||
virtual bool initElement(const std::vector<int>& MNPC)
|
virtual bool initElement(const std::vector<int>& MNPC)
|
||||||
@ -122,17 +134,18 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \brief Finalizes the element quantities after the numerical integration.
|
|
||||||
//! \details This method is invoked once for each element, after the numerical
|
// Integrand evaluation interface
|
||||||
//! integration loop is finished, and before the resulting element quantities
|
// ==============================
|
||||||
//! are assembled into their system level equivalents.
|
|
||||||
//! It can also be used to implement multiple integration point loops within
|
//! \brief Defines which FE quantities are needed by the integrand.
|
||||||
//! the same element, provided the necessary integration point values are
|
//! \return 1: The basis functions and their gradients are needed
|
||||||
//! stored internally in the object during the first integration loop.
|
//! \return 2: As 1, but in addition the second derivatives of the basis
|
||||||
virtual bool finalizeElement(LocalIntegral*&, const TimeDomain&)
|
//! functions and the characteristic element size is needed
|
||||||
{
|
//! \return 3: As 1, but in addition the volume-averaged basis functions
|
||||||
return true;
|
//! are needed
|
||||||
}
|
//! \return 4: As 1, but in addition the element center coordinates are needed
|
||||||
|
virtual int getIntegrandType() const { return 1; }
|
||||||
|
|
||||||
//! \brief Evaluates the integrand at an interior point.
|
//! \brief Evaluates the integrand at an interior point.
|
||||||
//! \param elmInt The local integral object to receive the contributions
|
//! \param elmInt The local integral object to receive the contributions
|
||||||
@ -163,6 +176,18 @@ public:
|
|||||||
return this->evalIntMx(elmInt,fe,X);
|
return this->evalIntMx(elmInt,fe,X);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! \brief Finalizes the element quantities after the numerical integration.
|
||||||
|
//! \details This method is invoked once for each element, after the numerical
|
||||||
|
//! integration loop over interior points is finished and before the resulting
|
||||||
|
//! element quantities are assembled into their system level equivalents.
|
||||||
|
//! It can also be used to implement multiple integration point loops within
|
||||||
|
//! the same element, provided the necessary integration point values are
|
||||||
|
//! stored internally in the object during the first integration loop.
|
||||||
|
virtual bool finalizeElement(LocalIntegral*&, const TimeDomain&)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//! \brief Evaluates the integrand at a boundary point.
|
//! \brief Evaluates the integrand at a boundary point.
|
||||||
//! \param elmInt The local integral object to receive the contributions
|
//! \param elmInt The local integral object to receive the contributions
|
||||||
//! \param[in] fe Finite element data of current integration point
|
//! \param[in] fe Finite element data of current integration point
|
||||||
@ -212,6 +237,10 @@ protected:
|
|||||||
const Vec3&, const Vec3&) const { return false; }
|
const Vec3&, const Vec3&) const { return false; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
// Solution field evaluation interface
|
||||||
|
// ===================================
|
||||||
|
|
||||||
//! \brief Evaluates the secondary solution at a result point.
|
//! \brief Evaluates the secondary solution at a result point.
|
||||||
//! \param[out] s The solution field values at current point
|
//! \param[out] s The solution field values at current point
|
||||||
//! \param[in] N Basis function values at current point
|
//! \param[in] N Basis function values at current point
|
||||||
@ -294,35 +323,24 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Various service methods
|
||||||
|
// =======================
|
||||||
|
|
||||||
//! \brief Writes surface tractions/fluxes for a given time step to VTF-file.
|
//! \brief Writes surface tractions/fluxes for a given time step to VTF-file.
|
||||||
//! \param vtf The VTF-file object to receive the tractions
|
virtual bool writeGlvT(VTF*, int, int&) const { return true; }
|
||||||
//! \param[in] iStep Load/time step identifier
|
|
||||||
//! \param nBlck Running result block counter
|
|
||||||
virtual bool writeGlvT(VTF* vtf, int iStep, int& nBlck) const { return true; }
|
|
||||||
|
|
||||||
//! \brief Returns whether there are any traction/flux values to write to VTF.
|
//! \brief Returns whether there are any traction/flux values to write to VTF.
|
||||||
virtual bool hasTractionValues() const { return false; }
|
virtual bool hasTractionValues() const { return false; }
|
||||||
|
|
||||||
//! \brief Returns which integrand to be used.
|
//! \brief Returns the number of (secondary) solution field components.
|
||||||
virtual int getIntegrandType() const { return 1; }
|
|
||||||
|
|
||||||
//! \brief Returns the number of secondary solution field components.
|
|
||||||
virtual size_t getNoFields() const { return 0; }
|
virtual size_t getNoFields() const { return 0; }
|
||||||
|
|
||||||
//! \brief Returns the number of secondary solution field components.
|
//! \brief Returns the name of a (secondary) solution field component.
|
||||||
virtual size_t getNoSecFields() const { return 0; }
|
virtual const char* getFieldLabel(size_t, const char* = 0) const { return 0; }
|
||||||
|
|
||||||
//! \brief Returns the name of a secondary solution field component.
|
|
||||||
//! \param[in] i Field component index
|
|
||||||
//! \param[in] prefix Name prefix for all components
|
|
||||||
virtual const char* getFieldLabel(size_t i, const char* prefix = 0) const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! \brief Returns a pointer to an Integrand for solution norm evaluation.
|
//! \brief Returns a pointer to an Integrand for solution norm evaluation.
|
||||||
//! \param[in] asol Pointer to the analytical solution (optional)
|
virtual NormBase* getNormIntegrand(AnaSol* = 0) const { return 0; }
|
||||||
virtual NormBase* getNormIntegrand(AnaSol* asol = 0) const { return 0; }
|
|
||||||
|
|
||||||
//! \brief Returns the number of solution vectors.
|
//! \brief Returns the number of solution vectors.
|
||||||
size_t getNoSolutions() const { return primsol.size(); }
|
size_t getNoSolutions() const { return primsol.size(); }
|
||||||
@ -331,7 +349,7 @@ public:
|
|||||||
Vector& getSolution(size_t n = 0) { return primsol[n]; }
|
Vector& getSolution(size_t n = 0) { return primsol[n]; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Vectors primsol; //!< Primary solution vectors for this patch
|
Vectors primsol; //!< Primary solution vectors for current patch
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -402,7 +402,7 @@ bool NonLinSIM::saveStep (int iStep, double time, int* nViz, bool psolOnly)
|
|||||||
|
|
||||||
// Write solution fields
|
// Write solution fields
|
||||||
if (!solution.empty())
|
if (!solution.empty())
|
||||||
if (!model->writeGlvS(solution.front(),nViz,iStep,nBlock,psolOnly))
|
if (!model->writeGlvS(solution.front(),nViz,iStep,nBlock,time,psolOnly))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Write element norms (only when no additional visualization points are used)
|
// Write element norms (only when no additional visualization points are used)
|
||||||
@ -426,6 +426,12 @@ void NonLinSIM::dumpStep (int iStep, double time, std::ostream& os,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool NonLinSIM::dumpResults (double time, std::ostream& os) const
|
||||||
|
{
|
||||||
|
return model->dumpResults(solution.front(),time,os);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool NonLinSIM::project ()
|
bool NonLinSIM::project ()
|
||||||
{
|
{
|
||||||
return model->project(solution.front());
|
return model->project(solution.front());
|
||||||
|
@ -96,14 +96,19 @@ public:
|
|||||||
//! \param[in] psolOnly If \e true, skip secondary solution field output
|
//! \param[in] psolOnly If \e true, skip secondary solution field output
|
||||||
bool saveStep(int iStep, double time, int* nViz, bool psolOnly = false);
|
bool saveStep(int iStep, double time, int* nViz, bool psolOnly = false);
|
||||||
|
|
||||||
//! \brief Dumps the primary solution to given stream for inspection.
|
//! \brief Dumps the primary solution for inspection.
|
||||||
//! \param[in] iStep Load/time step identifier
|
//! \param[in] iStep Load/time step identifier
|
||||||
//! \param[in] time Current time/load parameter
|
//! \param[in] time Current time/load parameter
|
||||||
//! \param[in] os The output streeam to write to
|
//! \param[in] os The output stream to write the solution to
|
||||||
//! \param[in] withID If \e true, write node ID and coordinates too
|
//! \param[in] withID If \e true, write node ID and coordinates too
|
||||||
void dumpStep(int iStep, double time, std::ostream& os,
|
void dumpStep(int iStep, double time, std::ostream& os,
|
||||||
bool withID = true) const;
|
bool withID = true) const;
|
||||||
|
|
||||||
|
//! \brief Dumps solution variables at user-defined points.
|
||||||
|
//! \param[in] time Current time/load parameter
|
||||||
|
//! \param[in] os The output stream to write the solution to
|
||||||
|
bool dumpResults(double time, std::ostream& os) const;
|
||||||
|
|
||||||
//! \brief Returns a const reference to current solution vector.
|
//! \brief Returns a const reference to current solution vector.
|
||||||
const Vector& getSolution() const { return solution.front(); }
|
const Vector& getSolution() const { return solution.front(); }
|
||||||
|
|
||||||
|
@ -26,13 +26,13 @@
|
|||||||
#include "ElmNorm.h"
|
#include "ElmNorm.h"
|
||||||
#include "AnaSol.h"
|
#include "AnaSol.h"
|
||||||
#include "Tensor.h"
|
#include "Tensor.h"
|
||||||
#include "Vec3.h"
|
|
||||||
#include "Vec3Oper.h"
|
#include "Vec3Oper.h"
|
||||||
#include "EigSolver.h"
|
#include "EigSolver.h"
|
||||||
#include "Profiler.h"
|
#include "Profiler.h"
|
||||||
#include "ElementBlock.h"
|
#include "ElementBlock.h"
|
||||||
#include "VTF.h"
|
#include "VTF.h"
|
||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
|
#include <iomanip>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ bool SIMbase::parse (char* keyWord, std::istream& is)
|
|||||||
|
|
||||||
char* cline = 0;
|
char* cline = 0;
|
||||||
nGlPatches = 0;
|
nGlPatches = 0;
|
||||||
for (int i = 0; i < nproc && (cline = utl::readLine(is));i++)
|
for (int i = 0; i < nproc && (cline = utl::readLine(is)); i++)
|
||||||
{
|
{
|
||||||
int proc = atoi(strtok(cline," "));
|
int proc = atoi(strtok(cline," "));
|
||||||
int first = atoi(strtok(NULL," "));
|
int first = atoi(strtok(NULL," "));
|
||||||
@ -127,6 +127,30 @@ bool SIMbase::parse (char* keyWord, std::istream& is)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (!strncasecmp(keyWord,"RESULTPOINTS",12))
|
||||||
|
{
|
||||||
|
int nres = atoi(keyWord+12);
|
||||||
|
if (myPid == 0 && nres > 0)
|
||||||
|
std::cout <<"\nNumber of result points: "<< nres;
|
||||||
|
|
||||||
|
char* cline = 0;
|
||||||
|
myPoints.resize(nres);
|
||||||
|
for (int i = 0; i < nres && (cline = utl::readLine(is)); i++)
|
||||||
|
{
|
||||||
|
myPoints[i].patch = atoi(strtok(cline," "));
|
||||||
|
if (myPid == 0)
|
||||||
|
std::cout <<"\n\tPoint "<< i+1 <<": P"<< myPoints[i].patch <<" xi =";
|
||||||
|
for (int j = 0; j < 3 && (cline = strtok(NULL," ")); j++)
|
||||||
|
{
|
||||||
|
myPoints[i].param[j] = atof(cline);
|
||||||
|
if (myPid == 0)
|
||||||
|
std::cout <<' '<< myPoints[i].param[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (myPid == 0 && nres > 0)
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
else if (isalpha(keyWord[0]))
|
else if (isalpha(keyWord[0]))
|
||||||
std::cerr <<" *** SIMbase::parse: Unknown keyword: "<< keyWord << std::endl;
|
std::cerr <<" *** SIMbase::parse: Unknown keyword: "<< keyWord << std::endl;
|
||||||
|
|
||||||
@ -134,6 +158,15 @@ bool SIMbase::parse (char* keyWord, std::istream& is)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SIMbase::readLinSolParams (std::istream& is, int npar)
|
||||||
|
{
|
||||||
|
if (!mySolParams)
|
||||||
|
mySolParams = new LinSolParams();
|
||||||
|
|
||||||
|
mySolParams->read(is,npar);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SIMbase::createFEMmodel ()
|
bool SIMbase::createFEMmodel ()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < myModel.size(); i++)
|
for (size_t i = 0; i < myModel.size(); i++)
|
||||||
@ -267,6 +300,34 @@ bool SIMbase::preprocess (const std::vector<int>& ignoredPatches, bool fixDup)
|
|||||||
// Resolve possibly chained multi-point constraints
|
// Resolve possibly chained multi-point constraints
|
||||||
ASMbase::resolveMPCchains(myModel);
|
ASMbase::resolveMPCchains(myModel);
|
||||||
|
|
||||||
|
// Preprocess the result points
|
||||||
|
for (ResPointVec::iterator p = myPoints.begin(); p != myPoints.end();)
|
||||||
|
{
|
||||||
|
int pid = this->getLocalPatchIndex(p->patch);
|
||||||
|
if (pid < 1 || myModel[pid-1]->empty())
|
||||||
|
p = myPoints.erase(p);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->npar = myModel[pid-1]->getNoParamDim();
|
||||||
|
myModel[pid-1]->evalPoint(p->param,p->param,p->X);
|
||||||
|
|
||||||
|
std::cout <<"\nResult point #"<< 1+(int)(p-myPoints.begin())
|
||||||
|
<<": patch #"<< p->patch;
|
||||||
|
switch (p->npar) {
|
||||||
|
case 1: std::cout <<" u="; break;
|
||||||
|
case 2: std::cout <<" (u,v)=("; break;
|
||||||
|
case 3: std::cout <<" (u,v,w)=("; break;
|
||||||
|
}
|
||||||
|
std::cout << p->param[0];
|
||||||
|
for (unsigned char c = 1; c < p->npar; c++)
|
||||||
|
std::cout <<','<< p->param[c];
|
||||||
|
if (p->npar > 1) std::cout <<')';
|
||||||
|
std::cout <<", X = "<< p->X;
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
// Initialize data structures for the algebraic system
|
// Initialize data structures for the algebraic system
|
||||||
#ifdef PARALLEL_PETSC
|
#ifdef PARALLEL_PETSC
|
||||||
mySam = new SAMpatchPara(l2gn);
|
mySam = new SAMpatchPara(l2gn);
|
||||||
@ -337,10 +398,11 @@ bool SIMbase::setMode (int mode)
|
|||||||
|
|
||||||
void SIMbase::printProblem (std::ostream& os) const
|
void SIMbase::printProblem (std::ostream& os) const
|
||||||
{
|
{
|
||||||
if (!myProblem) return;
|
if (myProblem)
|
||||||
|
{
|
||||||
std::cout <<"\nProblem definition:"<< std::endl;
|
std::cout <<"\nProblem definition:"<< std::endl;
|
||||||
myProblem->print(os);
|
myProblem->print(os);
|
||||||
|
}
|
||||||
|
|
||||||
#if SP_DEBUG > 1
|
#if SP_DEBUG > 1
|
||||||
std::cout <<"\nProperty mapping:";
|
std::cout <<"\nProperty mapping:";
|
||||||
@ -493,6 +555,33 @@ bool SIMbase::assembleSystem (const TimeDomain& time, const Vectors& prevSol,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SIMbase::finalizeAssembly (bool newLHSmatrix)
|
||||||
|
{
|
||||||
|
// Communication of matrix and vector assembly (for PETSc only)
|
||||||
|
SystemMatrix* A = myEqSys->getMatrix();
|
||||||
|
if (A && newLHSmatrix)
|
||||||
|
{
|
||||||
|
if (!A->beginAssembly()) return false;
|
||||||
|
if (!A->endAssembly()) return false;
|
||||||
|
#if SP_DEBUG > 3
|
||||||
|
std::cout <<"\nSystem coefficient matrix:"<< *A;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemVector* b = myEqSys->getVector();
|
||||||
|
if (b)
|
||||||
|
{
|
||||||
|
if (!b->beginAssembly()) return false;
|
||||||
|
if (!b->endAssembly()) return false;
|
||||||
|
#if SP_DEBUG > 2
|
||||||
|
std::cout <<"\nSystem right-hand-side vector:"<< *b;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SIMbase::extractLoadVec (Vector& loadVec) const
|
bool SIMbase::extractLoadVec (Vector& loadVec) const
|
||||||
{
|
{
|
||||||
SystemVector* b = myEqSys->getVector();
|
SystemVector* b = myEqSys->getVector();
|
||||||
@ -612,7 +701,7 @@ bool SIMbase::solutionNorms (const TimeDomain& time, const Vectors& psol,
|
|||||||
|
|
||||||
myProblem->initIntegration(time);
|
myProblem->initIntegration(time);
|
||||||
|
|
||||||
size_t nNorms = norm->getNoFields() + norm->getNoSecFields();
|
size_t nNorms = norm->getNoFields();
|
||||||
const Vector& primsol = psol.front();
|
const Vector& primsol = psol.front();
|
||||||
|
|
||||||
size_t i, nel = mySam->getNoElms();
|
size_t i, nel = mySam->getNoElms();
|
||||||
@ -913,8 +1002,8 @@ bool SIMbase::writeGlvV (const Vector& vec, const char* fieldName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SIMbase::writeGlvS (const Vector& psol,
|
bool SIMbase::writeGlvS (const Vector& psol, const int* nViz,
|
||||||
const int* nViz, int iStep, int& nBlock, bool psolOnly)
|
int iStep, int& nBlock, double time, bool psolOnly)
|
||||||
{
|
{
|
||||||
if (psol.empty())
|
if (psol.empty())
|
||||||
return true;
|
return true;
|
||||||
@ -922,7 +1011,7 @@ bool SIMbase::writeGlvS (const Vector& psol,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!psolOnly)
|
if (!psolOnly)
|
||||||
myProblem->initResultPoints();
|
myProblem->initResultPoints(time);
|
||||||
|
|
||||||
Matrix field;
|
Matrix field;
|
||||||
size_t i, j;
|
size_t i, j;
|
||||||
@ -1193,12 +1282,12 @@ void SIMbase::dumpPrimSol (const Vector& psol, std::ostream& os,
|
|||||||
|
|
||||||
bool SIMbase::dumpGeometry (std::ostream& os) const
|
bool SIMbase::dumpGeometry (std::ostream& os) const
|
||||||
{
|
{
|
||||||
bool retVal = true;
|
for (size_t i = 0; i < myModel.size(); i++)
|
||||||
for (size_t i = 0; i < myModel.size() && retVal; i++)
|
|
||||||
if (!myModel[i]->empty())
|
if (!myModel[i]->empty())
|
||||||
retVal = myModel[i]->write(os);
|
if (!myModel[i]->write(os))
|
||||||
|
return false;
|
||||||
|
|
||||||
return retVal;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1239,7 +1328,7 @@ bool SIMbase::dumpSolution (const Vector& psol, std::ostream& os) const
|
|||||||
|
|
||||||
// Evaluate secondary solution variables
|
// Evaluate secondary solution variables
|
||||||
LocalSystem::patch = i;
|
LocalSystem::patch = i;
|
||||||
if (!myModel[i]->evalSolution(field,*myProblem,0))
|
if (!myModel[i]->evalSolution(field,*myProblem))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Write the secondary solution
|
// Write the secondary solution
|
||||||
@ -1256,34 +1345,63 @@ bool SIMbase::dumpSolution (const Vector& psol, std::ostream& os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SIMbase::readLinSolParams (std::istream& is, int npar)
|
bool SIMbase::dumpResults (const Vector& psol, double time, std::ostream& os,
|
||||||
|
std::streamsize outputPrecision) const
|
||||||
{
|
{
|
||||||
if (!mySolParams) mySolParams = new LinSolParams();
|
if (psol.empty() || myPoints.empty())
|
||||||
mySolParams->read(is,npar);
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
|
myProblem->initResultPoints(time);
|
||||||
|
|
||||||
bool SIMbase::finalizeAssembly (bool newLHSmatrix)
|
size_t i, j, k;
|
||||||
{
|
Matrix sol1, sol2;
|
||||||
// Communication of matrix and vector assembly (for PETSC only)
|
|
||||||
SystemMatrix* A = myEqSys->getMatrix();
|
for (i = 0; i < myModel.size(); i++)
|
||||||
if (A && newLHSmatrix)
|
|
||||||
{
|
{
|
||||||
if (!A->beginAssembly()) return false;
|
if (myModel[i]->empty()) continue; // skip empty patches
|
||||||
if (!A->endAssembly()) return false;
|
|
||||||
#if SP_DEBUG > 3
|
|
||||||
std::cout <<"\nSystem coefficient matrix:"<< *A;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemVector* b = myEqSys->getVector();
|
ResPointVec::const_iterator p;
|
||||||
if (b)
|
std::vector<size_t> points;
|
||||||
{
|
RealArray params[3];
|
||||||
if (!b->beginAssembly()) return false;
|
|
||||||
if (!b->endAssembly()) return false;
|
// Find all evaluation points within this patch, if any
|
||||||
#if SP_DEBUG > 3
|
for (j = 0, p = myPoints.begin(); p != myPoints.end(); j++, p++)
|
||||||
std::cout <<"\nSystem right-hand-side vector:"<< *b;
|
if (this->getLocalPatchIndex(p->patch) == (int)(i+1))
|
||||||
#endif
|
{
|
||||||
|
points.push_back(j+1);
|
||||||
|
for (k = 0; k < myModel[i]->getNoParamDim(); k++)
|
||||||
|
params[k].push_back(p->param[k]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (points.empty()) continue; // no points in this patch
|
||||||
|
|
||||||
|
// Evaluate the primary solution variables
|
||||||
|
myModel[i]->extractNodeVec(psol,myProblem->getSolution());
|
||||||
|
if (!myModel[i]->evalSolution(sol1,myProblem->getSolution(),params,false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Evaluate the secondary solution variables
|
||||||
|
LocalSystem::patch = i;
|
||||||
|
if (!myModel[i]->evalSolution(sol2,*myProblem,params,false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Formatted output, use scientific notation with fixed field width
|
||||||
|
std::streamsize flWidth = 8 + outputPrecision;
|
||||||
|
std::streamsize oldPrec = os.precision(outputPrecision);
|
||||||
|
std::ios::fmtflags oldF = os.flags(std::ios::scientific | std::ios::right);
|
||||||
|
for (j = 0; j < points.size(); j++)
|
||||||
|
{
|
||||||
|
os <<" Result point #"<< points[j];
|
||||||
|
os <<": sol1 =";
|
||||||
|
for (k = 1; k <= sol1.rows(); k++)
|
||||||
|
os << std::setw(flWidth) << sol1(k,j+1);
|
||||||
|
os <<" sol2 =";
|
||||||
|
for (k = 1; k <= sol2.rows(); k++)
|
||||||
|
os << std::setw(flWidth) << sol2(k,j+1);
|
||||||
|
os << std::endl;
|
||||||
|
}
|
||||||
|
os.precision(oldPrec);
|
||||||
|
os.flags(oldF);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1293,13 +1411,14 @@ bool SIMbase::finalizeAssembly (bool newLHSmatrix)
|
|||||||
bool SIMbase::project (Vector& psol)
|
bool SIMbase::project (Vector& psol)
|
||||||
{
|
{
|
||||||
Matrix values;
|
Matrix values;
|
||||||
Vector psol2(psol.size());
|
Vector ssol(psol.size());
|
||||||
for (size_t i = 0; i < myModel.size(); ++i) {
|
for (size_t i = 0; i < myModel.size(); i++)
|
||||||
|
{
|
||||||
myModel[i]->extractNodeVec(psol,myProblem->getSolution());
|
myModel[i]->extractNodeVec(psol,myProblem->getSolution());
|
||||||
myModel[i]->evalSolution(values,*myProblem,NULL);
|
if (!myModel[i]->evalSolution(values,*myProblem)) return false;
|
||||||
myModel[i]->injectNodeVec(values,psol2);
|
myModel[i]->injectNodeVec(values,ssol);
|
||||||
}
|
}
|
||||||
psol = psol2;
|
psol = ssol;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "TimeDomain.h"
|
#include "TimeDomain.h"
|
||||||
#include "Property.h"
|
#include "Property.h"
|
||||||
#include "Function.h"
|
#include "Function.h"
|
||||||
|
#include "Vec3.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
class ASMbase;
|
class ASMbase;
|
||||||
@ -39,11 +40,28 @@ struct Mode
|
|||||||
int eigNo; //!< Eigenvalue identifier
|
int eigNo; //!< Eigenvalue identifier
|
||||||
double eigVal; //!< Eigenvalue associated with this mode
|
double eigVal; //!< Eigenvalue associated with this mode
|
||||||
Vector eigVec; //!< Eigenvector associated with this mode
|
Vector eigVec; //!< Eigenvector associated with this mode
|
||||||
// \brief Default constructor setting \a eigNo and \a eigVal to zero.
|
// \brief Default constructor.
|
||||||
Mode() { eigNo = 0; eigVal = 0.0; }
|
Mode() : eigNo(0), eigVal(0.0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Struct defining a result sampling point.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct ResultPoint
|
||||||
|
{
|
||||||
|
unsigned char npar; //!< Number of parameters
|
||||||
|
size_t patch; //!< Patch index [0,nPatch>
|
||||||
|
double param[3]; //!< Parameters of the point (u,v,w)
|
||||||
|
Vec3 X; //!< Spatial coordinates of the point
|
||||||
|
// \brief Default constructor.
|
||||||
|
ResultPoint() : npar(0), patch(0) { param[0] = param[1] = param[2] = 0.0; }
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<ResultPoint> ResPointVec; //!< Result point container
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Base class for NURBS-based FEM simulators.
|
\brief Base class for NURBS-based FEM simulators.
|
||||||
\details This class incapsulates data and methods need for solving
|
\details This class incapsulates data and methods need for solving
|
||||||
@ -136,10 +154,9 @@ public:
|
|||||||
bool assembleSystem(const TimeDomain& time, const Vectors& pSol = Vectors(),
|
bool assembleSystem(const TimeDomain& time, const Vectors& pSol = Vectors(),
|
||||||
bool newLHSmatrix = true);
|
bool newLHSmatrix = true);
|
||||||
|
|
||||||
//! \brief Finalize system assembly.
|
//! \brief Finalizes system assembly.
|
||||||
// TODO: This HAS to be called from subclasses if assembleSystem
|
//TODO: This HAS to be called from subclasses if assembleSystem is overridden.
|
||||||
// is overridden. This need to be fixed, probably through
|
// This need to be fixed, probably through a wrapper function.
|
||||||
// a wrapper function
|
|
||||||
bool finalizeAssembly(bool newLHSmatrix);
|
bool finalizeAssembly(bool newLHSmatrix);
|
||||||
|
|
||||||
//! \brief Administers assembly of the linear equation system.
|
//! \brief Administers assembly of the linear equation system.
|
||||||
@ -262,9 +279,10 @@ public:
|
|||||||
//! \param[in] nViz Number of visualization points over each knot-span
|
//! \param[in] nViz Number of visualization points over each knot-span
|
||||||
//! \param[in] iStep Load/time step identifier
|
//! \param[in] iStep Load/time step identifier
|
||||||
//! \param nBlock Running result block counter
|
//! \param nBlock Running result block counter
|
||||||
|
//! \param[in] time Load/time step parameter
|
||||||
//! \param[in] psolOnly If \e true, skip secondary solution field evaluation
|
//! \param[in] psolOnly If \e true, skip secondary solution field evaluation
|
||||||
virtual bool writeGlvS(const Vector& psol, const int* nViz, int iStep,
|
virtual bool writeGlvS(const Vector& psol, const int* nViz, int iStep,
|
||||||
int& nBlock, bool psolOnly = false);
|
int& nBlock, double time = 0.0, bool psolOnly = false);
|
||||||
|
|
||||||
//! \brief Writes a mode shape and associated eigenvalue to the VTF-file.
|
//! \brief Writes a mode shape and associated eigenvalue to the VTF-file.
|
||||||
//! \details The eigenvalue is used as a label on the step state info
|
//! \details The eigenvalue is used as a label on the step state info
|
||||||
@ -299,6 +317,13 @@ public:
|
|||||||
//! \param[in] psol Primary solution vector to derive other quantities from
|
//! \param[in] psol Primary solution vector to derive other quantities from
|
||||||
//! \param os Output stream to write the solution data to
|
//! \param os Output stream to write the solution data to
|
||||||
bool dumpSolution(const Vector& psol, std::ostream& os) const;
|
bool dumpSolution(const Vector& psol, std::ostream& os) const;
|
||||||
|
//! \brief Dumps solution results at specified points in ASCII format.
|
||||||
|
//! \param[in] psol Primary solution vector to derive other quantities from
|
||||||
|
//! \param[in] time Load/time step parameter
|
||||||
|
//! \param os Output stream to write the solution data to
|
||||||
|
//! \param[in] outputPrecision Number of digits after the decimal point
|
||||||
|
bool dumpResults(const Vector& psol, double time, std::ostream& os,
|
||||||
|
std::streamsize outputPrecision = 3) const;
|
||||||
//! \brief Dumps the primary solution in ASCII format for inspection.
|
//! \brief Dumps the primary solution in ASCII format for inspection.
|
||||||
//! \param[in] psol Primary solution vector
|
//! \param[in] psol Primary solution vector
|
||||||
//! \param os Output stream to write the solution data to
|
//! \param os Output stream to write the solution data to
|
||||||
@ -376,6 +401,7 @@ protected:
|
|||||||
Integrand* myProblem; //!< Problem-specific data and methods
|
Integrand* myProblem; //!< Problem-specific data and methods
|
||||||
AnaSol* mySol; //!< Analytical/Exact solution
|
AnaSol* mySol; //!< Analytical/Exact solution
|
||||||
VTF* myVtf; //!< VTF-file for result visualization
|
VTF* myVtf; //!< VTF-file for result visualization
|
||||||
|
ResPointVec myPoints; //!< User-defined result sampling points
|
||||||
|
|
||||||
// Parallel computing attributes
|
// Parallel computing attributes
|
||||||
int nGlPatches; //!< Number of global patches
|
int nGlPatches; //!< Number of global patches
|
||||||
|
Loading…
Reference in New Issue
Block a user