Added: Unit test for NonLinSIM with line search
This commit is contained in:
parent
cae3aa4e8e
commit
85a7024501
@ -109,7 +109,7 @@ public:
|
|||||||
if (myProblem->getMode() == SIM::MASS_ONLY) {
|
if (myProblem->getMode() == SIM::MASS_ONLY) {
|
||||||
ElmMats elm;
|
ElmMats elm;
|
||||||
elm.resize(1,1); elm.redim(1);
|
elm.resize(1,1); elm.redim(1);
|
||||||
elm.A[0].fill(M); // Mass Matrix
|
elm.A[0].fill(M); // Mass matrix
|
||||||
ok = myEqSys->assemble(&elm,1);
|
ok = myEqSys->assemble(&elm,1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -159,7 +159,7 @@ public:
|
|||||||
NewmarkMats elm(intPrm[0],intPrm[1],intPrm[2],intPrm[3]);
|
NewmarkMats elm(intPrm[0],intPrm[1],intPrm[2],intPrm[3]);
|
||||||
elm.resize(3,1); elm.redim(2); elm.vec.resize(3);
|
elm.resize(3,1); elm.redim(2); elm.vec.resize(3);
|
||||||
elm.setStepSize(time.dt,0);
|
elm.setStepSize(time.dt,0);
|
||||||
elm.A[1](1,1) = elm.A[1](2,2) = M; // Mass Matrix
|
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](1,1) = elm.A[2](2,2) = K; // Stiffness matrix
|
||||||
elm.A[2](2,1) = elm.A[2](1,2) = -K;
|
elm.A[2](2,1) = elm.A[2](1,2) = -K;
|
||||||
elm.b[0] = elm.A[2]*prevSol.front(); // Elastic forces
|
elm.b[0] = elm.A[2]*prevSol.front(); // Elastic forces
|
||||||
|
139
src/SIM/Test/TestNonLinSIM.C
Normal file
139
src/SIM/Test/TestNonLinSIM.C
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
// $Id$
|
||||||
|
//==============================================================================
|
||||||
|
//!
|
||||||
|
//! \file TestNonLinSIM.C
|
||||||
|
//!
|
||||||
|
//! \date Nov 25 2016
|
||||||
|
//!
|
||||||
|
//! \author Knut Morten Okstad / SINTEF
|
||||||
|
//!
|
||||||
|
//! \brief Tests the nonlinear quasi-static solution driver.
|
||||||
|
//!
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include "SAM.h"
|
||||||
|
#include "IntegrandBase.h"
|
||||||
|
#include "SIMoutput.h"
|
||||||
|
#include "SIMdummy.h"
|
||||||
|
|
||||||
|
#include "NonLinSIM.h"
|
||||||
|
#include "ElmMats.h"
|
||||||
|
#include "AlgEqSystem.h"
|
||||||
|
#include "TimeStep.h"
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
|
|
||||||
|
// SAM class representing a single-DOF system.
|
||||||
|
class SAM1DOF : public SAM
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SAM1DOF()
|
||||||
|
{
|
||||||
|
nmmnpc = nel = nnod = ndof = neq = 1;
|
||||||
|
mmnpc = new int[1]; mmnpc[0] = 1;
|
||||||
|
mpmnpc = new int[2]; std::iota(mpmnpc,mpmnpc+2,1);
|
||||||
|
madof = new int[2]; std::iota(madof,madof+2,1);
|
||||||
|
msc = new int[1]; msc[0] = 1;
|
||||||
|
EXPECT_TRUE(this->initSystemEquations());
|
||||||
|
}
|
||||||
|
virtual ~SAM1DOF() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Dummy integrand class.
|
||||||
|
class Dummy : public IntegrandBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Dummy() : IntegrandBase(1) {}
|
||||||
|
virtual ~Dummy() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Simulator class for a single-DOF skew bar.
|
||||||
|
class Bar1DOF : public SIMdummy<SIMoutput>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Bar1DOF(IntegrandBase* p) : SIMdummy<SIMoutput>(p) { mySam = new SAM1DOF(); }
|
||||||
|
virtual ~Bar1DOF() {}
|
||||||
|
virtual bool assembleSystem(const TimeDomain&, const Vectors& prevSol,
|
||||||
|
bool newLHSmatrix, bool)
|
||||||
|
{
|
||||||
|
const double x = 5.0; // Initial X-coordinate of end point
|
||||||
|
const double y = 2.0; // Initial Y-coordinate of end point
|
||||||
|
const double K = 26925.824035673; // Axial stiffness
|
||||||
|
const double F = -200.0; // External load (constant)
|
||||||
|
|
||||||
|
double u = prevSol.front().front(); // Current deflection
|
||||||
|
double L = hypot(x,y+u); // Current length of the bar
|
||||||
|
double L0 = hypot(x,y); // Initial length of the bar
|
||||||
|
double eps = L/L0 - 1.0; // Axial strain
|
||||||
|
double N = K*eps; // Axial force
|
||||||
|
double Km = K/L0; // Nominal material stiffness
|
||||||
|
double Kg = N/L; // Nominal geometric stiffness
|
||||||
|
|
||||||
|
Vec3 X(x/L,(y+u)/L,0.0); // Beam axis
|
||||||
|
Vec3 Y(-X.y,X.x,0.0); // Normal axis
|
||||||
|
|
||||||
|
ElmMats elm;
|
||||||
|
elm.resize(1,1);
|
||||||
|
elm.redim(1);
|
||||||
|
elm.vec.resize(1);
|
||||||
|
elm.A.front().fill(Km*X.y*X.y + Kg*Y.y*Y.y); // Stiffness matrix
|
||||||
|
elm.b.front().fill(-N*X.y); // Internal forces
|
||||||
|
elm.vec.front() = prevSol.front();
|
||||||
|
myEqSys->initialize(newLHSmatrix);
|
||||||
|
if (!myEqSys->assemble(&elm,1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Add in the external load
|
||||||
|
if (!mySam->assembleSystem(*myEqSys->getVector(),&F,1))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return myEqSys->finalize(newLHSmatrix);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Nonlinear simulation driver with line search.
|
||||||
|
class TestNonLinSIM : public NonLinSIM
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TestNonLinSIM(SIMbase& sim, double lsTol = 0.0) : NonLinSIM(sim)
|
||||||
|
{
|
||||||
|
eta = lsTol;
|
||||||
|
rTol = 1.0e-16;
|
||||||
|
}
|
||||||
|
virtual ~TestNonLinSIM() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void runSingleDof (NonLinSIM& solver, int& n, double& s)
|
||||||
|
{
|
||||||
|
TimeStep tp;
|
||||||
|
ASSERT_TRUE(solver.initSol());
|
||||||
|
ASSERT_TRUE(solver.advanceStep(tp));
|
||||||
|
ASSERT_EQ(solver.solveStep(tp),SIM::CONVERGED);
|
||||||
|
s = solver.getSolution().front(); n = tp.iter;
|
||||||
|
std::cout <<" Solution "<< s <<" obtained in "<< n <<" iterations.\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST(TestNonLinSIM, SingleDOF)
|
||||||
|
{
|
||||||
|
Bar1DOF simulator(new Dummy());
|
||||||
|
ASSERT_TRUE(simulator.initSystem(0));
|
||||||
|
|
||||||
|
TestNonLinSIM integrator1(simulator);
|
||||||
|
TestNonLinSIM integrator2(simulator,0.0001);
|
||||||
|
|
||||||
|
int n1, n2;
|
||||||
|
double s1, s2;
|
||||||
|
runSingleDof(integrator1,n1,s1);
|
||||||
|
runSingleDof(integrator2,n2,s2);
|
||||||
|
|
||||||
|
EXPECT_FLOAT_EQ(s1,s2);
|
||||||
|
EXPECT_EQ(n1,5);
|
||||||
|
EXPECT_EQ(n2,3);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user