Skip to content

Commit

Permalink
Assembly is now a module
Browse files Browse the repository at this point in the history
  • Loading branch information
cbritopacheco committed Nov 13, 2023
1 parent a3d7075 commit fbcd6a5
Show file tree
Hide file tree
Showing 19 changed files with 244 additions and 105 deletions.
11 changes: 11 additions & 0 deletions doc/Namespaces.dox
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@
@brief Module for dealing with geometries.
*/

/**
@dir Rodin/Assembly
@brief Namespace @ref Rodin::Assembly
*/

/**
@namespace Rodin::Assembly
@brief Module for performing the assembly of linear algebra objects from
variational expressions.
*/

/**
@dir Rodin/Geometry/Euclidean
@brief Namespace @ref Rodin::Geometry::Euclidean
Expand Down
4 changes: 4 additions & 0 deletions src/Rodin/Assembly/AssemblyBase.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include "AssemblyBase.h"

namespace Rodin::Assembly
{}
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,29 @@
* (See accompanying file LICENSE or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef RODIN_VARIATIONAL_ASSEMBLY_H
#define RODIN_VARIATIONAL_ASSEMBLY_H
#ifndef RODIN_ASSEMBLY_ASSEMBLYBASE_H
#define RODIN_ASSEMBLY_ASSEMBLYBASE_H

#include "Rodin/FormLanguage/List.h"

#include "Rodin/Math.h"

#include "Rodin/Variational/FiniteElementSpace.h"
#include "Rodin/Variational/LinearFormIntegrator.h"
#include "Rodin/Variational/BilinearFormIntegrator.h"
#include "Rodin/Geometry/Mesh.h"
#include "Rodin/Variational/ForwardDecls.h"
#include "ForwardDecls.h"

namespace Rodin::Variational::Assembly
namespace Rodin::Assembly
{
struct BilinearAssemblyInput
{
const Geometry::MeshBase& mesh;
const FiniteElementSpaceBase& trialFES;
const FiniteElementSpaceBase& testFES;
FormLanguage::List<BilinearFormIntegratorBase>& bfis;
const Variational::FiniteElementSpaceBase& trialFES;
const Variational::FiniteElementSpaceBase& testFES;
FormLanguage::List<Variational::BilinearFormIntegratorBase>& bfis;
};

template <class OperatorType>
class AssemblyBase<BilinearFormBase<OperatorType>>
class AssemblyBase<Variational::BilinearFormBase<OperatorType>>
: public FormLanguage::Base
{
public:
Expand All @@ -42,15 +42,15 @@ namespace Rodin::Variational::Assembly
};

template <class VectorType>
class AssemblyBase<LinearFormBase<VectorType>>
class AssemblyBase<Variational::LinearFormBase<VectorType>>
: public FormLanguage::Base
{
public:
struct Input
{
const Geometry::MeshBase& mesh;
const FiniteElementSpaceBase& fes;
FormLanguage::List<LinearFormIntegratorBase>& lfis;
const Variational::FiniteElementSpaceBase& fes;
FormLanguage::List<Variational::LinearFormIntegratorBase>& lfis;
};

AssemblyBase() = default;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
set(RodinVariational_HEADERS
set(RodinAssembly_HEADERS
AssemblyBase.h
Native.h)
Serial.h
Multithreaded.h)

set(RodinVariational_SRCS
set(RodinAssembly_SRCS
AssemblyBase.cpp
Native.cpp)
Serial.cpp
Multithreaded.h)

add_library(RodinAssembly
${RodinAssembly_SRCS} ${RodinAssembly_HEADERS})
Expand All @@ -18,16 +20,10 @@ endif()

# ---- Link targets ----------------------------------------------------------
target_include_directories(RodinAssembly
INTERFACE
$<TARGET_PROPERTY:Rodin,INTERFACE_INCLUDE_DIRECTORIES>
PUBLIC
${MFEM_INCLUDE_DIRS})
INTERFACE $<TARGET_PROPERTY:Rodin,INTERFACE_INCLUDE_DIRECTORIES>)

target_link_libraries(RodinAssembly
PUBLIC
Rodin::IO
Rodin::Alert
Rodin::Utility
Rodin::Geometry
Rodin::FormLanguage
Rodin::Variational)
19 changes: 19 additions & 0 deletions src/Rodin/Assembly/ForwardDecls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef RODIN_ASSEMBLY_FORWARDDECLS_H
#define RODIN_ASSEMBLY_FORWARDDECLS_H

namespace Rodin::Assembly
{
template <class Operand>
class AssemblyBase;

template <class Operand>
class Serial;

template <class Operand>
class Multithreaded;

template <class Operand>
class OpenMP;
}

#endif
129 changes: 129 additions & 0 deletions src/Rodin/Assembly/Multithreaded.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* Copyright Carlos BRITO PACHECO 2021 - 2022.
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE or copy at
* https://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef RODIN_ASSEMBLY_Multithreaded_H
#define RODIN_ASSEMBLY_Multithreaded_H

#include "Rodin/Math/Vector.h"
#include "Rodin/Math/SparseMatrix.h"

#include "ForwardDecls.h"
#include "AssemblyBase.h"

namespace Rodin::Assembly
{
template <>
class Multithreaded<Variational::BilinearFormBase<std::vector<Eigen::Triplet<Scalar>>>>
: public AssemblyBase<Variational::BilinearFormBase<std::vector<Eigen::Triplet<Scalar>>>>
{
/**
* @internal
*/
static void add(
std::vector<Eigen::Triplet<Scalar>>& out, const Math::Matrix& in,
const IndexArray& rows, const IndexArray& cols);

public:
using Parent =
AssemblyBase<Variational::BilinearFormBase<std::vector<Eigen::Triplet<Scalar>>>>;
using OperatorType = std::vector<Eigen::Triplet<Scalar>>;

Multithreaded() = default;

Multithreaded(const Multithreaded& other)
: Parent(other)
{}

Multithreaded(Multithreaded&& other)
: Parent(std::move(other))
{}

/**
* @brief Executes the assembly and returns the linear operator
* associated to the bilinear form.
*/
OperatorType execute(const BilinearAssemblyInput& input) const override;

Multithreaded* copy() const noexcept override
{
return new Multithreaded(*this);
}
};

/**
* @brief Multithreaded assembly of the Math::SparseMatrix associated to a
* BilinearFormBase object.
*/
template <>
class Multithreaded<Variational::BilinearFormBase<Math::SparseMatrix>>
: public AssemblyBase<Variational::BilinearFormBase<Math::SparseMatrix>>
{
public:
using Parent = AssemblyBase<Variational::BilinearFormBase<Math::SparseMatrix>>;
using OperatorType = Math::SparseMatrix;

Multithreaded() = default;

Multithreaded(const Multithreaded& other)
: Parent(other)
{}

Multithreaded(Multithreaded&& other)
: Parent(std::move(other))
{}

/**
* @brief Executes the assembly and returns the linear operator
* associated to the bilinear form.
*/
OperatorType execute(const BilinearAssemblyInput& input) const override;

Multithreaded* copy() const noexcept override
{
return new Multithreaded(*this);
}
};

/**
* @brief %Multithreaded assembly of the Math::Vector associated to a LinearFormBase
* object.
*/
template <>
class Multithreaded<Variational::LinearFormBase<Math::Vector>>
: public AssemblyBase<Variational::LinearFormBase<Math::Vector>>
{

static void add(Math::Vector& out, const Math::Vector& in, const IndexArray& s);

public:
using Parent = AssemblyBase<Variational::LinearFormBase<Math::Vector>>;
using VectorType = Math::Vector;

Multithreaded() = default;

Multithreaded(const Multithreaded& other)
: Parent(other)
{}

Multithreaded(Multithreaded&& other)
: Parent(std::move(other))
{}

/**
* @brief Executes the assembly and returns the vector associated to the
* linear form.
*/
VectorType execute(const Input& input) const override;

Multithreaded* copy() const noexcept override
{
return new Multithreaded(*this);
}
};
}

#endif

File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,23 @@
#include "Rodin/Variational/LinearFormIntegrator.h"
#include "Rodin/Variational/BilinearFormIntegrator.h"

#include "Native.h"
#include "Serial.h"

namespace Rodin::Variational::Assembly
namespace Rodin::Assembly
{
Math::SparseMatrix Native<BilinearFormBase<Math::SparseMatrix>>
Math::SparseMatrix
Serial<Variational::BilinearFormBase<Math::SparseMatrix>>
::execute(const BilinearAssemblyInput& input) const
{
Native<BilinearFormBase<std::vector<Eigen::Triplet<Scalar>>>> assembly;
Serial<Variational::BilinearFormBase<std::vector<Eigen::Triplet<Scalar>>>> assembly;
const auto triplets = assembly.execute(input);
OperatorType res(input.testFES.getSize(), input.trialFES.getSize());
res.setFromTriplets(triplets.begin(), triplets.end());
return res;
}

void Native<BilinearFormBase<std::vector<Eigen::Triplet<Scalar>>>>
void
Serial<Variational::BilinearFormBase<std::vector<Eigen::Triplet<Scalar>>>>
::add(std::vector<Eigen::Triplet<Scalar>>& out, const Math::Matrix& in,
const IndexArray& rows, const IndexArray& cols)
{
Expand All @@ -41,7 +43,8 @@ namespace Rodin::Variational::Assembly
}
}

std::vector<Eigen::Triplet<Scalar>> Native<BilinearFormBase<std::vector<Eigen::Triplet<Scalar>>>>
std::vector<Eigen::Triplet<Scalar>>
Serial<Variational::BilinearFormBase<std::vector<Eigen::Triplet<Scalar>>>>
::execute(const BilinearAssemblyInput& input) const
{
std::vector<Eigen::Triplet<Scalar>> res;
Expand All @@ -51,7 +54,7 @@ namespace Rodin::Variational::Assembly
const auto& attrs = bfi.getAttributes();
switch (bfi.getRegion())
{
case Integrator::Region::Domain:
case Variational::Integrator::Region::Domain:
{
for (auto it = input.mesh.getCell(); !it.end(); ++it)
{
Expand All @@ -67,7 +70,7 @@ namespace Rodin::Variational::Assembly
}
break;
}
case Integrator::Region::Faces:
case Variational::Integrator::Region::Faces:
{
for (auto it = input.mesh.getFace(); !it.end(); ++it)
{
Expand All @@ -83,7 +86,7 @@ namespace Rodin::Variational::Assembly
}
break;
}
case Integrator::Region::Boundary:
case Variational::Integrator::Region::Boundary:
{
for (auto it = input.mesh.getBoundary(); !it.end(); ++it)
{
Expand All @@ -99,7 +102,7 @@ namespace Rodin::Variational::Assembly
}
break;
}
case Integrator::Region::Interface:
case Variational::Integrator::Region::Interface:
{
for (auto it = input.mesh.getInterface(); !it.end(); ++it)
{
Expand All @@ -120,7 +123,8 @@ namespace Rodin::Variational::Assembly
return res;
}

void Native<LinearFormBase<Math::Vector>>
void
Serial<Variational::LinearFormBase<Math::Vector>>
::add(Math::Vector& out, const Math::Vector& in, const IndexArray& s)
{
assert(in.size() == s.size());
Expand All @@ -129,7 +133,8 @@ namespace Rodin::Variational::Assembly
out.coeffRef(global) += in.coeff(i++);
}

Math::Vector Native<LinearFormBase<Math::Vector>>
Math::Vector
Serial<Variational::LinearFormBase<Math::Vector>>
::execute(const Input& input) const
{
VectorType res(input.fes.getSize());
Expand All @@ -140,7 +145,7 @@ namespace Rodin::Variational::Assembly
const auto& attrs = lfi.getAttributes();
switch (lfi.getRegion())
{
case Integrator::Region::Domain:
case Variational::Integrator::Region::Domain:
{
for (auto it = input.mesh.getCell(); !it.end(); ++it)
{
Expand All @@ -155,7 +160,7 @@ namespace Rodin::Variational::Assembly
}
break;
}
case Integrator::Region::Faces:
case Variational::Integrator::Region::Faces:
{
for (auto it = input.mesh.getFace(); !it.end(); ++it)
{
Expand All @@ -170,7 +175,7 @@ namespace Rodin::Variational::Assembly
}
break;
}
case Integrator::Region::Boundary:
case Variational::Integrator::Region::Boundary:
{
for (auto it = input.mesh.getBoundary(); !it.end(); ++it)
{
Expand All @@ -185,7 +190,7 @@ namespace Rodin::Variational::Assembly
}
break;
}
case Integrator::Region::Interface:
case Variational::Integrator::Region::Interface:
{
for (auto it = input.mesh.getInterface(); !it.end(); ++it)
{
Expand Down
Loading

0 comments on commit fbcd6a5

Please sign in to comment.