Skip to content
Snippets Groups Projects
Commit cd9a2dbd authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add pressure boundary conditions for acoustic solver

parent b0263e5e
Branches
Tags
1 merge request!43Feature/glace boundary conditions
...@@ -57,6 +57,39 @@ class InterpolateItemValue<OutputType(InputType)> : public PugsFunctionAdapter<O ...@@ -57,6 +57,39 @@ class InterpolateItemValue<OutputType(InputType)> : public PugsFunctionAdapter<O
return value; return value;
} }
template <ItemType item_type>
static inline Array<OutputType>
interpolate(const FunctionSymbolId& function_symbol_id,
const ItemValue<const InputType, item_type>& position,
const Array<const ItemIdT<item_type>>& list_of_items)
{
auto& expression = Adapter::getFunctionExpression(function_symbol_id);
auto convert_result = Adapter::getResultConverter(expression.m_data_type);
Array<ExecutionPolicy> context_list = Adapter::getContextList(expression);
using execution_space = typename Kokkos::DefaultExecutionSpace::execution_space;
Kokkos::Experimental::UniqueToken<execution_space, Kokkos::Experimental::UniqueTokenScope::Global> tokens;
Array<OutputType> value{list_of_items.size()};
using ItemId = ItemIdT<item_type>;
parallel_for(list_of_items.size(), [=, &expression, &tokens](size_t i_item) {
ItemId item_id = list_of_items[i_item];
const int32_t t = tokens.acquire();
auto& execution_policy = context_list[t];
Adapter::convertArgs(execution_policy.currentContext(), position[item_id]);
auto result = expression.execute(execution_policy);
value[i_item] = convert_result(std::move(result));
tokens.release(t);
});
return value;
}
}; };
template <size_t Dimension> template <size_t Dimension>
...@@ -116,8 +149,20 @@ struct GlaceScheme ...@@ -116,8 +149,20 @@ struct GlaceScheme
const RefId& ref = ref_face_list.refId(); const RefId& ref = ref_face_list.refId();
if (ref == pressure_bc_descriptor.boundaryDescriptor()) { if (ref == pressure_bc_descriptor.boundaryDescriptor()) {
const auto& face_list = ref_face_list.list(); const auto& face_list = ref_face_list.list();
Array<double> face_values{face_list.size()};
face_values.fill(1); 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, m_mesh->xr(), face_list);
} else {
MeshDataType& mesh_data = MeshDataManager::instance().getMeshData(*m_mesh);
return InterpolateItemValue<double(
TinyVector<Dimension>)>::template interpolate<FaceType>(pressure_id, mesh_data.xl(), face_list);
}
}();
std::shared_ptr bc = std::shared_ptr bc =
std::make_shared<PressureBoundaryCondition<MeshType::Dimension>>(face_list, face_values); std::make_shared<PressureBoundaryCondition<MeshType::Dimension>>(face_list, face_values);
......
...@@ -35,13 +35,37 @@ class MeshData : public IMeshData ...@@ -35,13 +35,37 @@ class MeshData : public IMeshData
std::shared_ptr<NodeValuePerCell<const Rd>> m_Cjr; std::shared_ptr<NodeValuePerCell<const Rd>> m_Cjr;
std::shared_ptr<NodeValuePerCell<const double>> m_ljr; std::shared_ptr<NodeValuePerCell<const double>> m_ljr;
std::shared_ptr<NodeValuePerCell<const Rd>> m_njr; std::shared_ptr<NodeValuePerCell<const Rd>> m_njr;
FaceValue<const Rd> m_xl;
std::shared_ptr<CellValue<const Rd>> m_xj; std::shared_ptr<CellValue<const Rd>> m_xj;
std::shared_ptr<CellValue<const double>> m_Vj; std::shared_ptr<CellValue<const double>> m_Vj;
std::shared_ptr<NodeValuePerFace<const Rd>> m_Nlr; std::shared_ptr<NodeValuePerFace<const Rd>> m_Nlr;
PUGS_INLINE PUGS_INLINE
void void
_computeIsobarycenter() _computeFaceIsobarycenter()
{ // Computes vertices isobarycenter
if constexpr (Dimension == 1) {
static_assert(Dimension != 1, "xl does not make sense in 1d");
} else {
const NodeValue<const Rd>& xr = m_mesh.xr();
const auto& face_to_node_matrix = m_mesh.connectivity().faceToNodeMatrix();
FaceValue<Rd> xl(m_mesh.connectivity());
parallel_for(
m_mesh.numberOfFaces(), PUGS_LAMBDA(FaceId face_id) {
Rd X = zero;
const auto& face_nodes = face_to_node_matrix[face_id];
for (size_t R = 0; R < face_nodes.size(); ++R) {
X += xr[face_nodes[R]];
}
xl[face_id] = 1. / face_nodes.size() * X;
});
m_xl = xl;
}
}
void
_computeCellIsobarycenter()
{ // Computes vertices isobarycenter { // Computes vertices isobarycenter
if constexpr (Dimension == 1) { if constexpr (Dimension == 1) {
const NodeValue<const Rd>& xr = m_mesh.xr(); const NodeValue<const Rd>& xr = m_mesh.xr();
...@@ -337,12 +361,22 @@ class MeshData : public IMeshData ...@@ -337,12 +361,22 @@ class MeshData : public IMeshData
return *m_njr; return *m_njr;
} }
PUGS_INLINE
FaceValue<const Rd>
xl()
{
if (not m_xl.isBuilt()) {
this->_computeFaceIsobarycenter();
}
return m_xl;
}
PUGS_INLINE PUGS_INLINE
CellValue<const Rd> CellValue<const Rd>
xj() xj()
{ {
if (not m_xj) { if (not m_xj) {
this->_computeIsobarycenter(); this->_computeCellIsobarycenter();
} }
return *m_xj; return *m_xj;
} }
......
...@@ -132,8 +132,9 @@ class AcousticSolver ...@@ -132,8 +132,9 @@ class AcousticSolver
case BoundaryCondition::pressure: { case BoundaryCondition::pressure: {
const PressureBoundaryCondition<Dimension>& pressure_bc = const PressureBoundaryCondition<Dimension>& pressure_bc =
dynamic_cast<const PressureBoundaryCondition<Dimension>&>(handler.boundaryCondition()); dynamic_cast<const PressureBoundaryCondition<Dimension>&>(handler.boundaryCondition());
if constexpr (Dimension == 1) {
MeshData<Dimension>& mesh_data = MeshDataManager::instance().getMeshData(*m_mesh); MeshData<Dimension>& mesh_data = MeshDataManager::instance().getMeshData(*m_mesh);
if constexpr (Dimension == 1) {
const NodeValuePerCell<const Rd> Cjr = mesh_data.Cjr(); const NodeValuePerCell<const Rd> Cjr = mesh_data.Cjr();
const auto& node_to_cell_matrix = m_connectivity.nodeToCellMatrix(); const auto& node_to_cell_matrix = m_connectivity.nodeToCellMatrix();
...@@ -152,7 +153,32 @@ class AcousticSolver ...@@ -152,7 +153,32 @@ class AcousticSolver
m_br[node_id] -= value_list[i_node] * Cjr(node_cell_id, node_local_number_in_cell); m_br[node_id] -= value_list[i_node] * Cjr(node_cell_id, node_local_number_in_cell);
} }
} else { } else {
throw NotImplementedError("pressure bc in dimension>1"); const NodeValuePerFace<const Rd> Nlr = mesh_data.Nlr();
const auto& face_to_cell_matrix = m_connectivity.faceToCellMatrix();
const auto& face_to_node_matrix = m_connectivity.faceToNodeMatrix();
const auto& face_local_numbers_in_their_cells = m_connectivity.faceLocalNumbersInTheirCells();
const auto& face_cell_is_reversed = m_connectivity.cellFaceIsReversed();
const auto& face_list = pressure_bc.faceList();
const auto& value_list = pressure_bc.valueList();
for (size_t i_face = 0; i_face < face_list.size(); ++i_face) {
const FaceId face_id = face_list[i_face];
const auto& face_cell_list = face_to_cell_matrix[face_id];
Assert(face_cell_list.size() == 1);
CellId face_cell_id = face_cell_list[0];
size_t face_local_number_in_cell = face_local_numbers_in_their_cells(face_id, 0);
const double sign = face_cell_is_reversed(face_cell_id, face_local_number_in_cell) ? -1 : 1;
const auto& face_nodes = face_to_node_matrix[face_id];
for (size_t i_node = 0; i_node < face_nodes.size(); ++i_node) {
NodeId node_id = face_nodes[i_node];
m_br[node_id] -= sign * value_list[i_face] * Nlr(face_id, i_node);
}
}
} }
break; break;
} }
......
...@@ -21,6 +21,12 @@ class PressureBoundaryConditionDescriptor : public IBoundaryConditionDescriptor ...@@ -21,6 +21,12 @@ class PressureBoundaryConditionDescriptor : public IBoundaryConditionDescriptor
const FunctionSymbolId m_function_symbol_id; const FunctionSymbolId m_function_symbol_id;
public: public:
FunctionSymbolId
functionSymbolId() const
{
return m_function_symbol_id;
}
const IBoundaryDescriptor& const IBoundaryDescriptor&
boundaryDescriptor() const boundaryDescriptor() const
{ {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment