Select Git revision
AffectationProcessor.hpp
FluxingAdvectionSolver.cpp 5.02 KiB
#include <scheme/FluxingAdvectionSolver.hpp>
#include <language/utils/EvaluateAtPoints.hpp>
#include <mesh/Connectivity.hpp>
#include <mesh/IMesh.hpp>
#include <mesh/Mesh.hpp>
#include <scheme/DiscreteFunctionP0.hpp>
#include <scheme/DiscreteFunctionUtils.hpp>
#include <scheme/IDiscreteFunctionDescriptor.hpp>
template <size_t Dimension>
class FluxingAdvectionSolver
{
private:
using Rd = TinyVector<Dimension>;
using MeshType = Mesh<Connectivity<Dimension>>;
const std::shared_ptr<const MeshType> m_old_mesh;
const std::shared_ptr<const MeshType> m_new_mesh;
const DiscreteFunctionP0<Dimension, const double> m_old_q;
public:
// CellValue<double>
// compute_PFnp1(const DiscreteFunctionP0<Dimension, const double> F, const double& dt, const double& dx)
// {
// CellValue<double> PFnp1{m_mesh.connectivity()};
// DiscreteFunctionP0<Dimension, double> deltaF = compute_delta2Fn(F);
// DiscreteFunctionP0<Dimension, double> deltaF0 = compute_delta2Fn(m_Fn);
// for (CellId cell_id = 0; cell_id < m_mesh.numberOfCells(); ++cell_id) {
// PFnp1[cell_id] = m_Fn[cell_id][0] + m_Fn[cell_id][1] -
// (0.5 * dt / dx) * m_lambda * (deltaF[cell_id][0] - deltaF[cell_id][1]) -
// (0.5 * dt / dx) * m_lambda * (deltaF0[cell_id][0] - deltaF0[cell_id][1]);
// }
// return PFnp1;
// }
// DiscreteFunctionP0<Dimension, double>
// apply(const double& dt, const double& eps)
// {
// const DiscreteFunctionP0<Dimension, const double>& F0 = m_Fn;
// DiscreteFunctionP0<Dimension, double> Fnp1 = copy(F0);
// DiscreteFunctionP0<Dimension, double> deltaFn = compute_delta2Fn(F0);
// for (size_t p = 0; p < 2; ++p) {
// CellId first_cell_id = 0;
// const double dx = m_dx_table[first_cell_id];
// DiscreteFunctionP0<Dimension, double> deltaFnp1 = compute_delta2Fn(Fnp1);
// const CellValue<const double> PFnp1 = compute_PFnp1(Fnp1, dt, dx);
// const CellValue<const double> APFnp1 = getA(PFnp1);
// const CellArray<const double> MPFnp1 = compute_M(PFnp1, APFnp1);
// const CellValue<const double> PFn = compute_PFn(F0);
// const CellValue<const double> APFn = getA(PFn);
// const CellArray<const double> MPFn = compute_M(PFn, APFn);
// for (CellId cell_id = 0; cell_id < m_mesh.numberOfCells(); ++cell_id) {
// Fnp1[cell_id][0] = 1. / (1 + 0.5 * dt / eps) *
// ((0.5 * dt / eps) * MPFnp1[cell_id][0] + F0[cell_id][0] -
// (0.5 * dt / dx) * m_lambda * (deltaFnp1[cell_id][0] + deltaFn[cell_id][0]) +
// (0.5 * dt / eps) * (MPFn[cell_id][0] - F0[cell_id][0]));
// Fnp1[cell_id][1] = 1. / (1 + 0.5 * dt / eps) *
// ((0.5 * dt / eps) * MPFnp1[cell_id][1] + F0[cell_id][1] +
// (0.5 * dt / dx) * m_lambda * (deltaFnp1[cell_id][1] + deltaFn[cell_id][1]) +
// (0.5 * dt / eps) * (MPFn[cell_id][1] - F0[cell_id][1]));
// }
// }
// return Fnp1;
// }
DiscreteFunctionP0<Dimension, double>
apply()
{
DiscreteFunctionP0<Dimension, double> new_q(m_new_mesh);
if (m_new_mesh->shared_connectivity() != m_old_mesh->shared_connectivity()) {
throw NormalError("Old and new meshes must share the same connectivity");
}
return new_q;
}
FluxingAdvectionSolver(const std::shared_ptr<const MeshType> old_mesh,
const std::shared_ptr<const MeshType> new_mesh,
const DiscreteFunctionP0<Dimension, const double>& old_q)
: m_old_mesh{old_mesh}, m_new_mesh{new_mesh}
{}
~FluxingAdvectionSolver() = default;
};
std::shared_ptr<const DiscreteFunctionVariant>
FluxingAdvectionSolverHandler(const std::shared_ptr<const IMesh> new_mesh,
const std::shared_ptr<const DiscreteFunctionVariant>& old_q_v)
{
const std::shared_ptr<const IMesh> old_mesh = getCommonMesh({old_q_v});
if (not checkDiscretizationType({old_q_v}, DiscreteFunctionType::P0)) {
throw NormalError("acoustic solver expects P0 functions");
}
switch (old_mesh->dimension()) {
case 1: {
constexpr size_t Dimension = 1;
using MeshType = Mesh<Connectivity<Dimension>>;
const std::shared_ptr<const MeshType> old_mesh0 = std::dynamic_pointer_cast<const MeshType>(old_mesh);
const DiscreteFunctionP0<Dimension, const double>& old_q =
old_q_v->get<DiscreteFunctionP0<Dimension, const double>>();
const std::shared_ptr<const MeshType> new_mesh0 = std::dynamic_pointer_cast<const MeshType>(new_mesh);
FluxingAdvectionSolver<Dimension> solver(old_mesh0, new_mesh0, old_q);
return std::make_shared<DiscreteFunctionVariant>(solver.apply());
}
case 2: {
throw NotImplementedError("Fluxing advection solver not implemented in dimension 2");
}
case 3: {
throw NotImplementedError("Fluxing advection solver not implemented in dimension 3");
}
default: {
throw UnexpectedError("Invalid mesh dimension");
}
}
}