diff --git a/Base/ForceModel/imstkFEElasticityForceModel.h b/Base/ForceModel/imstkFEElasticityForceModel.h
index 9944df44387c57d48973217a6822dd5f3dabc138..c4834a58b088036c6225e77eaeaf7a1ff07c0056 100644
--- a/Base/ForceModel/imstkFEElasticityForceModel.h
+++ b/Base/ForceModel/imstkFEElasticityForceModel.h
@@ -24,6 +24,7 @@
 
 #include "g3log/g3log.hpp"
 
+#include "imstkInternalForceModel.h"
 #include "imstkMath.h"
 
 // Vega
@@ -45,7 +46,7 @@ public:
     ///
     /// \brief Constructor
     ///
-    FEElasticityForceModel(const TimeIntegrator::Type type);
+    FEElasticityForceModel();
 
     ///
     /// \brief Destructor
@@ -55,9 +56,9 @@ public:
     void getInternalForce(Vectord& u, Vectord& internalForce) override
     {
         m_feElasticForceModel->GetInternalForce(u.data(), internalForce.data());
-    };
+    }
 
-    void getTangentStiffnessMatrix(Vectord& u, std::shared_ptr<SparseMatrixd> tangentStiffnessMatrix) override
+    void getTangentStiffnessMatrix(Vectord& u, SparseMatrixd& tangentStiffnessMatrix) override
     {
         m_feElasticForceModel->GetTangentStiffnessMatrixTopology(u.data(), );
     }
diff --git a/Base/SceneElements/Objects/imstkDeformableBodyModel.cpp b/Base/SceneElements/Objects/imstkDeformableBodyModel.cpp
index e13709c5f7c7214a7c2e4d9e726afc798c249434..1c3fd16dca39743d1019536e3eb250f1123945f6 100644
--- a/Base/SceneElements/Objects/imstkDeformableBodyModel.cpp
+++ b/Base/SceneElements/Objects/imstkDeformableBodyModel.cpp
@@ -19,27 +19,402 @@
 
    =========================================================================*/
 
+#include <fstream>
+
 #include "imstkDeformableBodyModel.h"
+#include "generateMassMatrix.h"
 
 namespace imstk
 {
 
-void DeformableBodyModel::configure(const std::string& configFileName)
+DeformableBodyModel::DeformableBodyModel() : DynamicalModel(DynamicalModel::Type::elastoDynamics), m_damped(false){}
+
+void
+DeformableBodyModel::setForceModelConfiguration(std::shared_ptr<ForceModelConfig> fmConfig)
+{
+    m_forceModelConfiguration = fmConfig;
+}
+
+std::shared_ptr<imstk::ForceModelConfig>
+DeformableBodyModel::getForceModelConfiguration() const
+{
+    return m_forceModelConfiguration;
+}
+
+void
+DeformableBodyModel::setInternalForceModel(std::shared_ptr<InternalForceModel> fm)
+{
+    m_internalForceModel = fm;
+}
+
+std::shared_ptr<imstk::InternalForceModel>
+DeformableBodyModel::getInternalForceModel() const
+{
+    return m_internalForceModel;
+}
+
+void
+DeformableBodyModel::setTimeIntegrator(std::shared_ptr<TimeIntegrator> timeIntegrator)
+{
+    m_timeIntegrator = timeIntegrator;
+}
+
+std::shared_ptr<imstk::TimeIntegrator>
+DeformableBodyModel::getTimeIntegrator() const
+{
+    return m_timeIntegrator;
+}
+
+void
+DeformableBodyModel::setModelGeometry(std::shared_ptr<Geometry> geometry)
+{
+    m_forceModelGeometry = geometry;
+}
+
+std::shared_ptr<imstk::Geometry>
+DeformableBodyModel::getModelGeometry()
+{
+    return m_forceModelGeometry;
+}
+
+void
+DeformableBodyModel::configure(const std::string& configFileName)
 {
     m_forceModelConfiguration = std::make_shared<ForceModelConfig>(configFileName);
 }
 
-void DeformableBodyModel::initializeForceModel()
+bool
+DeformableBodyModel::loadBoundaryConditions()
+{
+    auto fileName = m_forceModelConfiguration->getStringOptionsMap().at("fixedDOFFilename");
+
+    if (fileName.empty())
+    {
+        LOG(WARNING) << "DeformableBodyModel::loadBoundaryConditions: The external boundary conditions file name is empty";
+        return false;
+    }
+    else
+    {
+        std::ifstream file(fileName.data());
+
+        if (file.is_open())
+        {
+            size_t index;
+            while (!file.eof())
+            {
+                file >> index;
+                m_fixedNodeIds.emplace_back(index);
+            }
+        }
+        else
+        {
+            LOG(WARNING) << "DeformableBodyModel::loadBoundaryConditions: Could not open external file with boundary conditions";
+            return false;
+        }
+
+        file.close();
+        return true;
+    }
+}
+
+void
+DeformableBodyModel::initializeForceModel()
+{
+    auto imstkVolMesh = std::static_pointer_cast<VolumetricMesh>(m_forceModelGeometry);
+    std::shared_ptr<vega::VolumetricMesh> vegaMesh = VegaMeshReader::getVegaVolumeMeshFromVolumeMesh(imstkVolMesh);
+
+    switch (m_forceModelConfiguration->getForceModelType())
+    {
+    case ForceModelType::StVK:
+
+        this->m_internalForceModel = std::make_shared<StVKForceModel>(vegaMesh);
+        break;
+
+    case ForceModelType::Linear:
+
+        this->m_internalForceModel = std::make_shared<LinearFEMForceModel>(vegaMesh);
+        break;
+
+    case ForceModelType::Corotational:
+
+        this->m_internalForceModel = std::make_shared<CorotationalFEMForceModel>(vegaMesh);
+        break;
+
+    case ForceModelType::Invertible:
+
+        this->m_internalForceModel = std::make_shared<IsotropicHyperelasticFEForceModel>(vegaMesh, -MAX_D);
+        break;
+
+    default:
+        LOG(WARNING) << "DeformableBodyModel::initializeForceModel: Unknown force model type";
+
+    } //switch
+}
+
+void
+DeformableBodyModel::initializeMassMatrix(const bool saveToDisk /*= false*/)
+{
+    if (!this->m_forceModelGeometry)
+    {
+        LOG(INFO) << "DeformableBodyModel::initializeMassMatrix Force model geometry not set!";
+        return;
+    }
+
+    vega::SparseMatrix *vegaMatrix;
+    auto imstkVolMesh = std::static_pointer_cast<VolumetricMesh>(m_forceModelGeometry);
+    std::shared_ptr<vega::VolumetricMesh> vegaMesh = VegaMeshReader::getVegaVolumeMeshFromVolumeMesh(imstkVolMesh);
+    vega::GenerateMassMatrix::computeMassMatrix(vegaMesh.get(), &vegaMatrix, true);
+
+    auto rowLengths = vegaMatrix->GetRowLengths();
+    auto nonZeroValues = vegaMatrix->GetEntries();
+    auto columnIndices = vegaMatrix->GetColumnIndices();
+
+    std::vector<Eigen::Triplet<double>> triplets;
+    triplets.reserve(vegaMatrix->GetNumEntries());
+    for (int i = 0, end = vegaMatrix->GetNumRows(); i < end; ++i)
+    {
+        for (int k = 0, k_end = rowLengths[i]; k < k_end; ++k)
+        {
+            triplets.emplace_back(i, columnIndices[i][k], nonZeroValues[i][k]);
+        }
+    }
+    m_M.resize(vegaMatrix->GetNumRows(), vegaMatrix->GetNumColumns());
+    m_M.setFromTriplets(std::begin(triplets), std::end(triplets));
+    m_M.makeCompressed();
+
+    /*this->vegaMassMatrix.reset(vegaMatrix);
+
+    if (saveToDisk)
+    {
+    char name[] = "ComputedMassMatrix.mass";
+    this->vegaMassMatrix->Save(name);
+    }*/
+}
+
+void
+DeformableBodyModel::initializeDampingMatrix()
+{
+    auto dampingLaplacianCoefficient =
+        this->m_forceModelConfiguration->getFloatsOptionsMap().at("dampingLaplacianCoefficient");
+
+    auto dampingMassCoefficient =
+        this->m_forceModelConfiguration->getFloatsOptionsMap().at("dampingMassCoefficient");
+
+    if (dampingLaplacianCoefficient == 0.0 || dampingMassCoefficient == 0.0)
+    {
+        m_damped = false;
+        return;
+    }
+    else
+    {
+        m_damped = true;
+    }
+
+    if (dampingLaplacianCoefficient <= 0.0)
+    {
+        LOG(INFO) << "DeformableBodyModel::initializeDampingMatrix Damping coefficient is negative!";
+        return;
+    }
+
+    auto imstkVolMesh = std::static_pointer_cast<VolumetricMesh>(m_forceModelGeometry);
+    std::shared_ptr<vega::VolumetricMesh> vegaMesh = VegaMeshReader::getVegaVolumeMeshFromVolumeMesh(imstkVolMesh);
+
+    auto meshGraph = std::make_shared<vega::Graph>(*vega::GenerateMeshGraph::Generate(this->m_forceModelGeometry.get()));
+
+    if (!meshGraph)
+    {
+        // TODO: log this
+        return;
+    }
+
+    vega::SparseMatrix *matrix;
+    meshGraph->GetLaplacian(&matrix, 1);
+
+    if (!matrix)
+    {
+        // TODO: log this
+        return;
+    }
+
+    matrix->ScalarMultiply(dampingLaplacianCoefficient);
+
+    auto rowLengths = matrix->GetRowLengths();
+    auto nonZeroValues = matrix->GetEntries();
+    auto columnIndices = matrix->GetColumnIndices();
+
+    std::vector<Eigen::Triplet<double>> triplets;
+    triplets.reserve(matrix->GetNumEntries());
+    for (int i = 0, end = matrix->GetNumRows(); i < end; ++i)
+    {
+        for (int k = 0, k_end = rowLengths[i]; k < k_end; ++k)
+        {
+            triplets.emplace_back(i, columnIndices[i][k], nonZeroValues[i][k]);
+        }
+    }
+
+    m_C.resize(matrix->GetNumRows(), matrix->GetNumColumns());
+    m_C.setFromTriplets(std::begin(triplets), std::end(triplets));
+    m_C.makeCompressed();
+
+    //this->dampingMatrix.reset(matrix);
+}
+
+void
+DeformableBodyModel::initializeTangentStiffness()
 {
+    if (!m_internalForceModel)
+    {
+        LOG(WARNING) << "Tangent stiffness cannot be initialized without force model";
+        return;
+    }
+
+    vega::SparseMatrix *matrix;
+    m_internalForceModel->GetTangentStiffnessMatrixTopology(&matrix);
+
+    if (!matrix)
+    {
+        // TODO: log this
+        return;
+    }
+
+    if (!this->vegaMassMatrix)
+    {
+        // TODO: log this
+        return;
+    }
+
+    matrix->BuildSubMatrixIndices(*this->vegaMassMatrix.get());
+
+    if (this->dampingMatrix)
+    {
+        matrix->BuildSubMatrixIndices(*this->dampingMatrix.get(), 1);
+    }
+
+    auto rowLengths = matrix->GetRowLengths();
+    auto columnIndices = matrix->GetColumnIndices();
 
+    std::vector<Eigen::Triplet<double>> triplets;
+    triplets.reserve(matrix->GetNumEntries());
+    for (int i = 0, end = matrix->GetNumRows(); i < end; ++i)
+    {
+        for (int k = 0, k_end = rowLengths[i]; k < k_end; ++k)
+        {
+            triplets.emplace_back(i, columnIndices[i][k], 0.001);
+        }
+    }
+    m_K.resize(matrix->GetNumRows(),
+        matrix->GetNumColumns());
+    m_K.setFromTriplets(std::begin(triplets), std::end(triplets));
+    m_K.makeCompressed();
+
+    this->vegaTangentStiffnessMatrix.reset(matrix);
+
+    const auto &dampingStiffnessCoefficient =
+        m_forceModelConfiguration->getFloatsOptionsMap().at("dampingStiffnessCoefficient");
+
+    const auto &dampingMassCoefficient =
+        m_forceModelConfiguration->getFloatsOptionsMap().at("dampingMassCoefficient");
+
+    // Initialize the Raleigh damping matrix
+    m_C = dampingMassCoefficient*m_M + m_K*dampingStiffnessCoefficient;
 }
 
-void DeformableBodyModel::initializeGravity()
+void
+DeformableBodyModel::initializeGravity()
 {
     m_gravityForce.resize(m_numDOF);
     m_gravityForce.setZero();
-    float gravityStrength = m_forceModelConfiguration->getFloatsOptionsMap().at("gravity");
-    this->volumetricMesh->computeGravity(this->gravity, this->gravityForce);
+    double gravity = m_forceModelConfiguration->getFloatsOptionsMap().at("gravity");
+
+    auto vegaMesh = VegaMeshReader::getVegaVolumeMeshFromVolumeMesh(std::static_pointer_cast<VolumetricMesh>(m_forceModelGeometry));
+    vegaMesh->computeGravity(m_gravityForce.data(), gravity);
+}
+
+void
+DeformableBodyModel::computeImplicitSystemRHS(const kinematicState& state,
+                                              const kinematicState& newState)
+{
+    // Do checks if there are uninitialized matrices
+
+    /*auto &M = this->evalMass(newState);
+    auto &K = this->evalDFx(newState);
+    auto &f = this->evalRHS(newState);*/
+
+    m_internalForceModel->getTangentStiffnessMatrix(newState.getQ(), m_K);
+
+    double timeStep = m_timeIntegrator->getTimestepSize();
+
+    m_Feff = m_M * (newState.getQDot() - state.getQDot()) / timeStep;
+    m_Feff -= m_K * (newState.getQ() - state.getQ() - newState.getQDot() * timeStep);
+    m_Feff += m_explicitExternalForce;
+    m_Feff += m_gravityForce;
+
+    if (m_damped)
+    {
+        m_Feff -= timeStep*this->Damping(newState)*newState.getQDot();
+    }
+    //state.applyBoundaryConditions(this->rhs);
+}
+
+void
+DeformableBodyModel::computeImplicitSystemLHS(const kinematicState& state,
+                                              const kinematicState& newState)
+{
+    // Do checks if there are uninitialized matrices
+
+
+    /*auto &M = this->evalMass(newState);
+    auto &K = this->evalDFx(newState);
+    auto &C = this->evalDFv(newState);*/
+
+    m_internalForceModel->getTangentStiffnessMatrix(newState.getQ(), m_K);
+
+    double timeStep = m_timeIntegrator->getTimestepSize();
+
+    m_Keff = (1.0 / timeStep) * m_M;
+    if (m_damped)
+    {
+        const auto &dampingStiffnessCoefficient =
+            m_forceModelConfiguration->getFloatsOptionsMap().at("dampingStiffnessCoefficient");
+
+        const auto &dampingMassCoefficient =
+            m_forceModelConfiguration->getFloatsOptionsMap().at("dampingMassCoefficient");
+
+        m_C = dampingMassCoefficient*m_M + m_K*dampingStiffnessCoefficient;
+        m_Keff += m_C;
+    }
+    m_Keff += timeStep * m_K;
+
+    //previousState.applyBoundaryConditions(this->systemMatrix);
+}
+
+void
+DeformableBodyModel::initializeExplicitExternalForces()
+{
+    m_explicitExternalForce.resize(m_numDOF);
+    m_explicitExternalForce.setZero();
+}
+
+NonLinearSystem::VectorFunctionType&
+DeformableBodyModel::getFunction(const Vectord& q)
+{
+    // Function to evaluate the nonlinear objective function.
+    return [&, this](const Vectord &) -> const Vectord&
+    {
+        computeImplicitSystemRHS(state, newState);
+        return m_Feff;
+    };
+}
+
+NonLinearSystem::MatrixFunctionType&
+DeformableBodyModel::getFunctionGradient(const Vectord& q)
+{
+    // Gradient of the nonlinear objective function.
+    return [&, this](const Vectord &) -> const SparseMatrixd&
+    {
+        computeImplicitSystemLHS(state, newState);
+        return m_Keff;
+    };
 }
 
 }
diff --git a/Base/SceneElements/Objects/imstkDeformableBodyModel.h b/Base/SceneElements/Objects/imstkDeformableBodyModel.h
index 06926cb4417db7236eebda9b5081dd002630a79b..f5308593df054ae8484098f18b6e0ecd3c8f7d09 100644
--- a/Base/SceneElements/Objects/imstkDeformableBodyModel.h
+++ b/Base/SceneElements/Objects/imstkDeformableBodyModel.h
@@ -24,14 +24,29 @@
 
 #include <memory>
 
+#include "Eigen/Sparse"
+
 #include "imstkGeometry.h"
 #include "imstkDynamicalModel.h"
 #include "imstkTimeIntegrator.h"
 #include "imstkInternalForceModel.h"
 #include "imstkForceModelConfig.h"
-#include "imstkKinematicState.h"
+#include "imstkProblemState.h"
+#include "imstkNonlinearSystem.h"
+#include "imstkVegaMeshReader.h"
+
+//force models
+#include "imstkStVKForceModel.h"
+#include "imstkLinearFEMForceModel.h"
+#include "imstkCorotationalFEMForceModel.h"
+#include "imstkIsotropicHyperelasticFEMForceModel.h"
+#include "imstkVegaMeshReader.h"
 
-namespace imstk {
+//vega
+#include "sparseMatrix.h"
+
+namespace imstk
+{
 
 ///
 /// \class DeformableBodyModel
@@ -51,11 +66,6 @@ public:
     ///
     virtual ~DeformableBodyModel() = default;
 
-    ///
-    /// \brief Set the geometry on which the force model acts
-    ///
-    void setForceModelGeometry(std::shared_ptr<Geometry> fmGeometry);
-
     ///
     /// \brief Set/Get force model configuration
     ///
@@ -63,10 +73,10 @@ public:
     std::shared_ptr<ForceModelConfig> getForceModelConfiguration() const;
 
     ///
-    /// \brief Set/Get force model
+    /// \brief Set/Get internal force model
     ///
-    void setForceModel(std::shared_ptr<InternalForceModel> fm);
-    std::shared_ptr<InternalForceModel> getForceModel() const;
+    void setInternalForceModel(std::shared_ptr<InternalForceModel> fm);
+    std::shared_ptr<InternalForceModel> getInternalForceModel() const;
 
     ///
     /// \brief Set/Get time integrator
@@ -75,15 +85,26 @@ public:
     std::shared_ptr<TimeIntegrator> getTimeIntegrator() const;
 
     ///
-    /// \brief Returns the tangent linear system for a given state
+    /// \brief Set/Get the geometry used by force model
     ///
-    void getLinearSystem();
+    void setModelGeometry(std::shared_ptr<Geometry> geometry);
+    std::shared_ptr<Geometry> getModelGeometry();
+
+    ///
+    /// \brief Returns the tangent linear system given curent state
+    ///
+    void getTangent(Vectord& q);
 
     ///
     /// \brief Configure the force model from external file
     ///
     void configure(const std::string& configFileName);
 
+    ///
+    /// \brief Initialize the deformable body model
+    ///
+    void initialize();
+
     ///
     /// \brief Load the boundary conditions from external file
     ///
@@ -114,31 +135,59 @@ public:
     ///
     void initializeGravity();
 
+    ///
+    /// \brief Compute the RHS of the resulting linear system
+    ///
+    void computeImplicitSystemRHS(const kinematicState& prevState,
+                                  const kinematicState& newState);
+
+    ///
+    /// \brief Compute the LHS of the resulting linear system
+    ///
+    void computeImplicitSystemLHS(const kinematicState& prevState,
+                                  const kinematicState& newState);
     ///
     /// \brief Initialize explicit external forces
     ///
     void initializeExplicitExternalForces();
 
-protected:
+    ///
+    /// \brief Returns the "function" that evaluates the nonlinear function given
+    /// the state vector
+    ///
+    NonLinearSystem::VectorFunctionType& getFunction(const Vectord& q);
 
-    std::shared_ptr<ForceModelConfig>   m_forceModelConfiguration;  ///> Store the configuration here
+    ///
+    /// \brief Returns the "function" that evaluates the gradient of the nonlinear
+    /// function given the state vector
+    ///
+    NonLinearSystem::MatrixFunctionType& getFunctionGradient(const Vectord& q);
 
+protected:
     std::shared_ptr<InternalForceModel> m_internalForceModel;       ///> Mathematical model for intenal forces
     std::shared_ptr<TimeIntegrator>     m_timeIntegrator;           ///> Time integrator
 
-    std::shared_ptr<Geometry> m_forceModelGeometry;    ///> Geometry used by force model
+    std::shared_ptr<ForceModelConfig>   m_forceModelConfiguration;  ///> Store the configuration here
+    std::shared_ptr<Geometry>           m_forceModelGeometry;       ///> Geometry used by force model
+
+    bool m_damped;
 
     /// Matrices typical to a elastodynamics and 2nd order analogous systems
-    std::shared_ptr<SparseMatrixd> m_M;    ///> Mass matrix
-    std::shared_ptr<SparseMatrixd> m_C;    ///> Damping coefficient matrix
-    std::shared_ptr<SparseMatrixd> m_K;    ///> Tangent (derivative of internal force w.r.t displacements) stiffness matrix
-    std::shared_ptr<SparseMatrixd> m_Keff; ///> Effective stiffness matrix (dependent on internal force model and time integrator)
+    SparseMatrixd m_M;    ///> Mass matrix
+    SparseMatrixd m_C;    ///> Damping coefficient matrix
+    SparseMatrixd m_K;    ///> Tangent (derivative of internal force w.r.t displacements) stiffness matrix
+    SparseMatrixd m_Keff; ///> Effective stiffness matrix (dependent on internal force model and time integrator)
+
+    Vectord m_Feff;       ///> Vector of gravity forces
 
     // External field forces
     Vectord m_gravityForce;   ///> Vector of gravity forces
 
     // Explicit external forces
     Vectord m_explicitExternalForce;   ///> Vector of explicitly defined external forces
+
+    // Dirichlet boundary conditions
+    std::vector<std::size_t> m_fixedNodeIds;
 };
 
 } // imstk