Commit c2293ba5 authored by GILLES Sebastien's avatar GILLES Sebastien
Browse files

#951 ShellMatrix: now the operation is set internally by the constructor; the...

#951 ShellMatrix: now the operation is set internally by the constructor; the context is expected to provide a method named ShellMatrixOperation().
parent b7171a83
......@@ -193,13 +193,13 @@ namespace HappyHeart
///@}
// Friendship to that free function given to Petsc can call dH method.
friend
PetscInt ApplydH<SolidVariationalFormulationPolicyT, AleT>(Mat shell_matrix, Vec x, Vec y);
//!
void dH(Vec petsc_input_vector, Vec& petsc_output_vector);
public:
//! The implementation of the operation expected by \a gmres_shell_matrix_ (dH in Freefem script).
void ShellMatrixOperation(Vec petsc_input_vector, Vec& petsc_output_vector);
private:
//! Init the global matrices and vectors.
void InitGlobalLinearAlgebra();
......
......@@ -158,23 +158,6 @@ namespace HappyHeart
invoking_file, invoking_line);
}
template<class SolidVariationalFormulationPolicyT, Ale AleT>
PetscInt ApplydH(Mat shell_matrix, Vec x, Vec y)
{
Model<SolidVariationalFormulationPolicyT, AleT>* context;
auto error_code = MatShellGetContext(shell_matrix, &context);
if (error_code)
throw Wrappers::Petsc::ExceptionNS::Exception(error_code, "MatShellGetContext",
__FILE__, __LINE__);
context->dH(x, y);
return 0;
}
template<class SolidVariationalFormulationPolicyT, Ale AleT>
const GlobalMatrix& Model<SolidVariationalFormulationPolicyT, AleT>
::GetSolidToFluidOnInterfaceInterpolationMatrix() const noexcept
......@@ -515,12 +498,8 @@ namespace HappyHeart
processor_wise_size, processor_wise_size,
program_wise_size, program_wise_size,
this,
MATOP_MULT,
__FILE__, __LINE__);
gmres_shell_matrix_->SetOperation(MATOP_MULT,
ApplydH<SolidVariationalFormulationPolicyT, AleT>,
__FILE__, __LINE__);
}
}
......
......@@ -145,8 +145,8 @@ namespace HappyHeart
template<class SolidVariationalFormulationPolicyT, Ale AleT>
void Model<SolidVariationalFormulationPolicyT, AleT>::dH(Vec petsc_input_vector,
Vec& petsc_output_vector)
void Model<SolidVariationalFormulationPolicyT, AleT>
::ShellMatrixOperation(Vec petsc_input_vector, Vec& petsc_output_vector)
{
// Copy the Petsc object into a wrapped one.
auto& input_displ_vector = GetNonCstVector<Solid::work_var_full_numbering_subset>();
......
......@@ -65,11 +65,14 @@ namespace HappyHeart
* \brief Constructor.
*
* \copydetails doxygen_hide_mpi_param
* \param[in] mat_op MatOperation object which specifies which operation is to be redefined for the
* shell matrix. So far only MATOP_MULT has been redefined this way in FSI model.
*/
explicit ShellMatrix(const Wrappers::Mpi& mpi,
unsigned int Nlocal_row, unsigned int Nlocal_column,
unsigned int Nglobal_row, unsigned int Nglobal_column,
ContextT* context,
MatOperation mat_op,
const char* invoking_file, int invoking_line);
//! Destructor.
......@@ -99,26 +102,29 @@ namespace HappyHeart
* method should be implemented over the function that might need access to the Vec internal object.
*/
Mat Internal() const noexcept;
private:
/*!
* \brief Thin wrapper over MatShellSetOperation.
*
* \param[in] mat_op MatOperation object which specifies which operation is to be redefined for the
* shell matrix. So far only MATOP_MULT has been redefined this way in FSI model.
* \param[in] impl Implementation of the method. This one must respect the prototype expected by Petsc
* (e.g. int (Mat, Vec, Vec) for MATOP_MULT and return 0 if all is fine.
*
*
* The implementation itself is expected to be given by ContextT::ShellMatrixOperation(). This one must
* respect the prototype expected by Petsc (e.g. int (Mat, Vec, Vec) for MATOP_MULT) and return 0 if
* all is fine.
*
*/
template<class ImplT>
void SetOperation(MatOperation mat_op, ImplT impl,
void SetOperation(MatOperation mat_op,
const char* invoking_file, int invoking_line);
private:
//! Underlying Petsc matrix.
Mat petsc_matrix_;
};
......
......@@ -40,6 +40,7 @@ namespace HappyHeart
unsigned int Nlocal_row, unsigned int Nlocal_column,
unsigned int Nglobal_row, unsigned int Nglobal_column,
ContextT* context,
MatOperation mat_op,
const char* invoking_file, int invoking_line)
{
int error_code = MatCreateShell(mpi.GetCommunicator(),
......@@ -51,31 +52,53 @@ namespace HappyHeart
&petsc_matrix_);
if (error_code)
throw ExceptionNS::Exception(error_code, "MatCreateShell", invoking_file, invoking_line);
throw ExceptionNS::Exception(error_code,
"MatCreateShell",
invoking_file, invoking_line);
SetOperation(mat_op, invoking_file, invoking_line);
}
template<class ContextT>
inline Mat ShellMatrix<ContextT>::Internal() const noexcept
inline PetscInt ApplyOperation(Mat shell_matrix, Vec x, Vec y)
{
assert(petsc_matrix_ != PETSC_NULL);
return petsc_matrix_;
ContextT* context;
auto error_code = MatShellGetContext(shell_matrix, &context);
if (error_code)
throw Wrappers::Petsc::ExceptionNS::Exception(error_code,
"MatShellGetContext",
__FILE__, __LINE__);
context->ShellMatrixOperation(x, y);
return 0;
}
template<class ContextT>
template<class ImplT>
void ShellMatrix<ContextT>::SetOperation(MatOperation mat_op, ImplT impl,
void ShellMatrix<ContextT>::SetOperation(MatOperation mat_op,
const char* invoking_file, int invoking_line)
{
auto error_code = MatShellSetOperation(Internal(),
mat_op,
reinterpret_cast<void(*)(void)>(impl));
int error_code = MatShellSetOperation(Internal(),
mat_op,
reinterpret_cast<void(*)(void)>(ApplyOperation<ContextT>));
if (error_code)
throw ExceptionNS::Exception(error_code, "MatShellSetOperation", invoking_file, invoking_line);
}
template<class ContextT>
inline Mat ShellMatrix<ContextT>::Internal() const noexcept
{
assert(petsc_matrix_ != PETSC_NULL);
return petsc_matrix_;
}
} //namespace Petsc
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment