Skip to content
Snippets Groups Projects

Feature/glace boundary conditions

9 files
+ 292
74
Compare changes
  • Side-by-side
  • Inline

Files

  • 9ab2f3e9
    Reorganize boundary conditions · 9ab2f3e9
    Stéphane Del Pino authored
    Now BC types are
    - Dirichlet
    - Fourier
    - Neumann
    - Symmetry
    
    One can set tags for Dirichlet, Neumann and Fourier in order to
    distinguish variables concerned by these conditions.
    
    In the future, it is planned to allow freefem like conditions such
    as `u = g on XMIN` or `alpha * u + dnu (u) = g on 3`,...
    
    However this will only make sense when "algorithms" will be set in
    pugs' language.
#include <language/algorithms/AcousticSolverAlgorithm.hpp>
#include <language/utils/InterpolateItemValue.hpp>
#include <output/VTKWriter.hpp>
#include <scheme/AcousticSolver.hpp>
#include <scheme/DirichletBoundaryConditionDescriptor.hpp>
#include <scheme/IBoundaryDescriptor.hpp>
#include <scheme/SymmetryBoundaryConditionDescriptor.hpp>
template <size_t Dimension>
AcousticSolverAlgorithm<Dimension>::AcousticSolverAlgorithm(
const AcousticSolverType& solver_type,
@@ -9,9 +16,12 @@ AcousticSolverAlgorithm<Dimension>::AcousticSolverAlgorithm(
const FunctionSymbolId& u_id,
const FunctionSymbolId& p_id)
{
std::shared_ptr<const MeshType> mesh = std::dynamic_pointer_cast<const MeshType>(i_mesh);
using ConnectivityType = Connectivity<Dimension>;
using MeshType = Mesh<ConnectivityType>;
using MeshDataType = MeshData<Dimension>;
using UnknownsType = FiniteVolumesEulerUnknowns<MeshType>;
std::cout << "number of bc descr = " << bc_descriptor_list.size() << '\n';
std::shared_ptr<const MeshType> mesh = std::dynamic_pointer_cast<const MeshType>(i_mesh);
typename AcousticSolver<MeshType>::BoundaryConditionList bc_list;
{
@@ -24,6 +34,8 @@ AcousticSolverAlgorithm<Dimension>::AcousticSolverAlgorithm(
}();
for (const auto& bc_descriptor : bc_descriptor_list) {
bool is_valid_boundary_condition = true;
switch (bc_descriptor->type()) {
case IBoundaryConditionDescriptor::Type::symmetry: {
using SymmetryBoundaryCondition = typename AcousticSolver<MeshType>::SymmetryBoundaryCondition;
@@ -39,72 +51,74 @@ AcousticSolverAlgorithm<Dimension>::AcousticSolverAlgorithm(
SymmetryBoundaryCondition{MeshFlatNodeBoundary<MeshType::Dimension>(mesh, ref_face_list)});
}
}
is_valid_boundary_condition = true;
break;
}
case IBoundaryConditionDescriptor::Type::velocity: {
using VelocityBoundaryCondition = typename AcousticSolver<MeshType>::VelocityBoundaryCondition;
const VelocityBoundaryConditionDescriptor& velocity_bc_descriptor =
dynamic_cast<const VelocityBoundaryConditionDescriptor&>(*bc_descriptor);
for (size_t i_ref_face_list = 0;
i_ref_face_list < mesh->connectivity().template numberOfRefItemList<FaceType>(); ++i_ref_face_list) {
const auto& ref_face_list = mesh->connectivity().template refItemList<FaceType>(i_ref_face_list);
const RefId& ref = ref_face_list.refId();
if (ref == velocity_bc_descriptor.boundaryDescriptor()) {
MeshNodeBoundary<Dimension> mesh_node_boundary{mesh, ref_face_list};
case IBoundaryConditionDescriptor::Type::dirichlet: {
const DirichletBoundaryConditionDescriptor& dirichlet_bc_descriptor =
dynamic_cast<const DirichletBoundaryConditionDescriptor&>(*bc_descriptor);
if (dirichlet_bc_descriptor.name() == "velocity") {
using VelocityBoundaryCondition = typename AcousticSolver<MeshType>::VelocityBoundaryCondition;
const FunctionSymbolId velocity_id = velocity_bc_descriptor.functionSymbolId();
for (size_t i_ref_face_list = 0;
i_ref_face_list < mesh->connectivity().template numberOfRefItemList<FaceType>(); ++i_ref_face_list) {
const auto& ref_face_list = mesh->connectivity().template refItemList<FaceType>(i_ref_face_list);
const RefId& ref = ref_face_list.refId();
if (ref == dirichlet_bc_descriptor.boundaryDescriptor()) {
MeshNodeBoundary<Dimension> mesh_node_boundary{mesh, ref_face_list};
const auto& node_list = mesh_node_boundary.nodeList();
const FunctionSymbolId velocity_id = dirichlet_bc_descriptor.rhsSymbolId();
Array<const TinyVector<Dimension>> value_list = InterpolateItemValue<TinyVector<Dimension>(
TinyVector<Dimension>)>::template interpolate<ItemType::node>(velocity_id, mesh->xr(), node_list);
const auto& node_list = mesh_node_boundary.nodeList();
bc_list.push_back(VelocityBoundaryCondition{node_list, value_list});
}
}
break;
}
case IBoundaryConditionDescriptor::Type::pressure: {
using PressureBoundaryCondition = typename AcousticSolver<MeshType>::PressureBoundaryCondition;
Array<const TinyVector<Dimension>> value_list = InterpolateItemValue<TinyVector<Dimension>(
TinyVector<Dimension>)>::template interpolate<ItemType::node>(velocity_id, mesh->xr(), node_list);
const PressureBoundaryConditionDescriptor& pressure_bc_descriptor =
dynamic_cast<const PressureBoundaryConditionDescriptor&>(*bc_descriptor);
for (size_t i_ref_face_list = 0;
i_ref_face_list < mesh->connectivity().template numberOfRefItemList<FaceType>(); ++i_ref_face_list) {
const auto& ref_face_list = mesh->connectivity().template refItemList<FaceType>(i_ref_face_list);
const RefId& ref = ref_face_list.refId();
if (ref == pressure_bc_descriptor.boundaryDescriptor()) {
const auto& face_list = ref_face_list.list();
const FunctionSymbolId pressure_id = pressure_bc_descriptor.functionSymbolId();
Array<const double> face_values = [&] {
if constexpr (Dimension == 1) {
return InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<FaceType>(pressure_id,
mesh->xr(),
face_list);
} else {
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*mesh);
return InterpolateItemValue<double(TinyVector<Dimension>)>::template interpolate<FaceType>(pressure_id,
mesh_data
.xl(),
face_list);
}
}();
bc_list.push_back(PressureBoundaryCondition{face_list, face_values});
bc_list.push_back(VelocityBoundaryCondition{node_list, value_list});
}
}
} else if (dirichlet_bc_descriptor.name() == "pressure") {
using PressureBoundaryCondition = typename AcousticSolver<MeshType>::PressureBoundaryCondition;
for (size_t i_ref_face_list = 0;
i_ref_face_list < mesh->connectivity().template numberOfRefItemList<FaceType>(); ++i_ref_face_list) {
const auto& ref_face_list = mesh->connectivity().template refItemList<FaceType>(i_ref_face_list);
const RefId& ref = ref_face_list.refId();
if (ref == dirichlet_bc_descriptor.boundaryDescriptor()) {
const auto& face_list = ref_face_list.list();
const FunctionSymbolId pressure_id = dirichlet_bc_descriptor.rhsSymbolId();
Array<const double> face_values = [&] {
if constexpr (Dimension == 1) {
return InterpolateItemValue<double(
TinyVector<Dimension>)>::template interpolate<FaceType>(pressure_id, mesh->xr(), face_list);
} else {
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*mesh);
return InterpolateItemValue<double(
TinyVector<Dimension>)>::template interpolate<FaceType>(pressure_id, mesh_data.xl(), face_list);
}
}();
bc_list.push_back(PressureBoundaryCondition{face_list, face_values});
}
}
} else {
is_valid_boundary_condition = false;
}
break;
}
default: {
is_valid_boundary_condition = false;
}
}
if (not is_valid_boundary_condition) {
std::ostringstream error_msg;
error_msg << *bc_descriptor << " is an invalid boundary condition for acoustic solver";
throw NormalError(error_msg.str());
}
}
}
}
Loading