コード例 #1
0
ファイル: TestNewmark.C プロジェクト: akva2/IFEM
  virtual bool assembleSystem(const TimeDomain& time,
                              const Vectors& prevSol,
                              bool newLHSmatrix, bool)
  {
    const double M = 10.0;   // Mass of the oscillator
    const double K = 1000.0; // Stiffness of the oscillator
    const double F = 1.0;    // External load (constant)

    myEqSys->initialize(newLHSmatrix);

    bool ok;
    if (myProblem->getMode() == SIM::MASS_ONLY) {
      ElmMats elm;
      elm.resize(1,1); elm.redim(1);
      elm.A[0].fill(M); // Mass Matrix
      ok = myEqSys->assemble(&elm,1);
    }
    else {
      const double* intPrm = static_cast<Problem*>(myProblem)->getIntPrm();
      NewmarkMats elm(intPrm[0],intPrm[1],intPrm[2],intPrm[3]);
      elm.resize(3,1); elm.redim(1); elm.vec.resize(3);
      elm.setStepSize(time.dt,0);
      elm.A[1].fill(M); // Mass matrix
      elm.A[2].fill(K); // Stiffness matrix
      elm.b[0] = -K*prevSol.front(); // Elastic forces
      for (int i = 0; i < 3; i++) elm.vec[i] = prevSol[i];
      ok = myEqSys->assemble(&elm,1);
    }

    // Add in the external load
    ok &= mySam->assembleSystem(*myEqSys->getVector(),&F,1);

    return ok && myEqSys->finalize(newLHSmatrix);
  }
コード例 #2
0
ファイル: TestNewmark.C プロジェクト: akva2/IFEM
  virtual bool assembleSystem(const TimeDomain& time,
                              const Vectors& prevSol,
                              bool newLHSmatrix, bool)
  {
    const double M = 1.0;    // Mass of the oscillator
    const double K = 1000.0; // Stiffness of the oscillator

    myEqSys->initialize(newLHSmatrix);

    bool ok;
    if (myProblem->getMode() == SIM::MASS_ONLY) {
      ElmMats elm;
      elm.resize(1,1); elm.redim(2);
      elm.A[0](1,1) = elm.A[0](2,2) = M; // Mass matrix
      ok = myEqSys->assemble(&elm,1);
    }
    else {
      const double* intPrm = static_cast<Problem*>(myProblem)->getIntPrm();
      NewmarkMats elm(intPrm[0],intPrm[1],intPrm[2],intPrm[3]);
      elm.resize(3,1); elm.redim(2); elm.vec.resize(3);
      elm.setStepSize(time.dt,0);
      elm.A[1](1,1) = elm.A[1](2,2) = M; // Mass Matrix
      elm.A[2](1,1) = elm.A[2](2,2) = K; // Stiffness matrix
      elm.A[2](2,1) = elm.A[2](1,2) = -K;
      elm.b[0] = elm.A[2]*prevSol.front(); // Elastic forces
      elm.b[0] *= -1.0;
      for (int i = 0; i < 3; i++) elm.vec[i] = prevSol[i];
      ok = myEqSys->assemble(&elm,1);
    }

    return ok && myEqSys->finalize(newLHSmatrix);
  }
コード例 #3
0
ファイル: SIMLinElKL.C プロジェクト: OPM/IFEM-Elasticity
double SIMLinElKL::externalEnergy (const Vectors& psol) const
{
  double energy = this->SIMbase::externalEnergy(psol);

  // External energy from the nodal point loads
  for (size_t i = 0; i < myLoads.size(); i++)
    energy += myLoads[i].pload * psol.front()(myLoads[i].inod);

  return energy;
}
コード例 #4
0
ファイル: NonlinearDriver.C プロジェクト: OPM/IFEM-Elasticity
bool NonlinearDriver::solutionNorms (const TimeDomain& time,
                                     double zero_tol, std::streamsize outPrec)
{
  if (msgLevel < 0 || solution.empty()) return true;

  const size_t nsd = model.getNoSpaceDim();

  size_t iMax[nsd];
  double dMax[nsd];
  double normL2 = model.solutionNorms(solution.front(),dMax,iMax);

  RealArray RF;
  bool haveReac = model.getCurrentReactions(RF,solution.front());

  Vectors gNorm;
  if (calcEn)
  {
    model.setMode(SIM::RECOVERY);
    model.setQuadratureRule(opt.nGauss[1]);
    if (!model.solutionNorms(time,solution,gNorm))
      gNorm.clear();
  }

  if (myPid > 0) return true;

  std::streamsize stdPrec = outPrec > 0 ? IFEM::cout.precision(outPrec) : 0;
  double old_tol = utl::zero_print_tol;
  utl::zero_print_tol = zero_tol;

  IFEM::cout <<"  Primary solution summary: L2-norm            : "
             << utl::trunc(normL2);

  for (unsigned char d = 0; d < nsd; d++)
    if (utl::trunc(dMax[d]) != 0.0)
      IFEM::cout <<"\n                            Max "<< char('X'+d)
                 <<"-displacement : "<< dMax[d] <<" node "<< iMax[d];

  if (haveReac)
  {
    IFEM::cout <<"\n  Total reaction forces: Sum(R) =";
    for (size_t i = 1; i < RF.size(); i++)
      IFEM::cout <<" "<< utl::trunc(RF[i]);
    if (utl::trunc(RF.front()) != 0.0)
      IFEM::cout <<"\n  displacement*reactions: (R,u) = "<< RF.front();
  }

  if (!gNorm.empty())
    this->printNorms(gNorm.front(),IFEM::cout);

  IFEM::cout << std::endl;
  utl::zero_print_tol = old_tol;
  if (stdPrec > 0) IFEM::cout.precision(stdPrec);
  return true;
}
コード例 #5
0
ファイル: SIMKLShell.C プロジェクト: kmokstad/IFEM-Elasticity
double SIMKLShell::externalEnergy (const Vectors& u,
                                   const TimeDomain& time) const
{
  double energy = this->SIMbase::externalEnergy(u,time);

  // External energy from the nodal point loads
  const int* madof = mySam->getMADOF();
  for (const PointLoad& load : myLoads)
    if (load.ldof.second > 0)
    {
      int idof = madof[load.ldof.first-1] + load.ldof.second-1;
      energy += (*load.p)(time.t) * u.front()(idof);
    }
    else if (load.ldof.second < 0) // This is an element point load
    {
      Vector v = this->SIMgeneric::getSolution(u.front(),load.xi,0,load.patch);
      if (-load.ldof.second <= (int)v.size())
        energy += (*load.p)(time.t) * v(-load.ldof.second);
    }

  return energy;
}
コード例 #6
0
ファイル: Elasticity.C プロジェクト: TheBB/IFEM-Elasticity
void ElasticityNorm::addBoundaryTerms (Vectors& gNorm, double energy) const
{
  gNorm.front()(2) += energy;
}
コード例 #7
0
ファイル: Elasticity.C プロジェクト: TheBB/IFEM-Elasticity
bool Elasticity::evalSol (Vector& s, const Vectors& eV, const FiniteElement& fe,
                          const Vec3& X, bool toLocal, Vec3* pdir) const
{
  if (eV.empty())
  {
    std::cerr <<" *** Elasticity::evalSol: No solutions vector."<< std::endl;
    return false;
  }
  else if (!eV.front().empty() && eV.front().size() != fe.dNdX.rows()*nsd)
  {
    std::cerr <<" *** Elasticity::evalSol: Invalid displacement vector."
	      <<"\n     size(eV) = "<< eV.front().size() <<"   size(dNdX) = "
	      << fe.dNdX.rows() <<","<< fe.dNdX.cols() << std::endl;
    return false;
  }

  // Evaluate the deformation gradient, dUdX, and/or the strain tensor, eps
  Matrix Bmat;
  Tensor dUdX(nDF);
  SymmTensor eps(nsd,axiSymmetry);
  if (!this->kinematics(eV.front(),fe.N,fe.dNdX,X.x,Bmat,dUdX,eps))
    return false;

  // Add strains due to temperature expansion, if any
  double epsT = this->getThermalStrain(eV.back(),fe.N,X);
  if (epsT != 0.0) eps -= epsT;

  // Calculate the stress tensor through the constitutive relation
  Matrix Cmat;
  SymmTensor sigma(nsd, axiSymmetry || material->isPlaneStrain()); double U;
  if (!material->evaluate(Cmat,sigma,U,fe,X,dUdX,eps))
    return false;
  else if (epsT != 0.0 && nsd == 2 && material->isPlaneStrain())
    sigma(3,3) -= material->getStiffness(X)*epsT;

  Vec3 p;
  bool havePval = false;
  if (toLocal && wantPrincipalStress)
  {
    // Calculate principal stresses and associated direction vectors
    if (sigma.size() == 4)
    {
      SymmTensor tmp(2); tmp = sigma; // discard the sigma_zz component
      havePval = pdir ? tmp.principal(p,pdir,2) : tmp.principal(p);
    }
    else
      havePval = pdir ? sigma.principal(p,pdir,2) : sigma.principal(p);

    // Congruence transformation to local coordinate system at current point
    if (locSys) sigma.transform(locSys->getTmat(X));
  }

  s = sigma;

  if (toLocal)
    s.push_back(sigma.vonMises());

  if (havePval)
  {
    s.push_back(p.x);
    s.push_back(p.y);
    if (sigma.dim() == 3)
      s.push_back(p.z);
  }

  return true;
}