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); }
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); }
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; }
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; }
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; }
void ElasticityNorm::addBoundaryTerms (Vectors& gNorm, double energy) const { gNorm.front()(2) += energy; }
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; }