The code snippet is as follows:
#include
#include<dolfin.h>
#include “ActiveLeftVentricle.h”
#include “StrainComputation.h”
#include
#include
class FiberDirections : public Expression
{
public:
// Create expression with 3 components
FiberDirections(
std::shared_ptr<MeshFunction> _c0,
std::shared_ptr<MeshFunction> _c1,
std::shared_ptr<MeshFunction> _c2) : Expression(3), c0(_c0), c1(_c1), c2(_c2) {}
// Function for evaluating expression on each cell
void eval(Eigen::Ref<Eigen::VectorXd> values, Eigen::Ref<const Eigen::VectorXd> x, const ufc::cell &cell) const override
{
const uint cell_index = cell.index;
values[0] = (*c0)[cell_index];
values[1] = (*c1)[cell_index];
values[2] = (*c2)[cell_index];
}
// The data stored in mesh functions
std::shared_ptr<dolfin::MeshFunction<double>> c0;
std::shared_ptr<dolfin::MeshFunction<double>> c1;
std::shared_ptr<dolfin::MeshFunction<double>> c2;
};
class RefConfiguration : public Expression
{
public:
RefConfiguration() : Expression(3)
{ }
void eval(Array<double> &values, const Array<double> &x) const
{
values[0] = x[0];
values[1] = x[1];
values[2] = x[2];
}
};
class OnBoundary : public SubDomain
{
bool inside(const Array& x, bool on_boundary) const
{
return x[0]>100;
}
};
class MyProblem : public NonlinearProblem
{
public:
MyProblem(std::shared_ptr<Mesh> mesh) : NonlinearProblem(){
std::cout<<"MyProblem constructor"<<std::endl;
auto V = std::make_shared<ActiveLeftVentricle::FunctionSpace>(mesh);
auto F = std::make_shared<ActiveLeftVentricle::Form_H>(V);
auto J = std::make_shared<ActiveLeftVentricle::Form_J>(V,V);
// u = std::make_shared<Function>(V);
// f = std::make_shared<Source>();
// F->u = u;
// F->f = f;
// J->u = u;
// Define fiber directions
std::cout<<"MyProblem constructor"<<std::endl;
auto f00 = std::make_shared<MeshFunction<double>>(mesh, "../fibers_0.xml");
auto f01 = std::make_shared<MeshFunction<double>>(mesh, "../fibers_1.xml");
auto f02 = std::make_shared<MeshFunction<double>>(mesh, "../fibers_2.xml");
auto s00 = std::make_shared<MeshFunction<double>>(mesh, "../sheets_0.xml");
auto s01 = std::make_shared<MeshFunction<double>>(mesh, "../sheets_1.xml");
auto s02 = std::make_shared<MeshFunction<double>>(mesh, "../sheets_2.xml");
auto f0 = std::make_shared<FiberDirections>(f00, f01, f02);
auto s0 = std::make_shared<FiberDirections>(s00, s01, s02);
// Define and set variables
std::cout<<"MyProblem constructor"<<std::endl;
X_current = std::make_shared<Function>(V);
X_start = std::make_shared<Function>(V);
pressure = std::make_shared<WallPressure>();
RefConfiguration ref_configuration;
X_start->interpolate(ref_configuration);
X_current->interpolate(ref_configuration);
// Define assembler of J and F
std::cout<<"MyProblem constructor"<<std::endl;
auto on_boundary = std::make_shared<OnBoundary>();
auto bc = std::make_shared<DirichletBC>(V, std::make_shared<Constant>(0.0, 0.0, 0.0), on_boundary);
std::vector<std::shared_ptr<const DirichletBC>> bcs = {bc};
assembler = std::make_shared<SystemAssembler>(J, F, bcs);
std::cout<<"MyProblem constructor"<<std::endl;
auto boundaries = std::make_shared<MeshFunction<std::size_t>>(mesh, "../boundaries.xml");
F->f0 = f0;
F->s0 = s0;
F->X = X_current;
F->x_start = X_start;
F->pressure = pressure;
F->ds = boundaries;
J->f0 = f0;
J->s0 = s0;
J->X = X_current;
J->x_start = X_start;
J->pressure = pressure;
J->ds = boundaries;
}
// Compute F at current point x
virtual void F(GenericVector& b, const GenericVector& x) override final {
// std::cout<<"F"<<std::endl;
assembler->assemble(b, x);
}
/// Compute J = F' at current point x
virtual void J(GenericMatrix& A, const GenericVector& x) override final {
// std::cout<<"J"<<std::endl;
assembler->assemble(A);
}
std::shared_ptr<SystemAssembler> assembler;
std::shared_ptr<Function> X_current;
std::shared_ptr<Function> X_start;
std::shared_ptr<WallPressure> pressure;
};
}