ForTrilinos
ForTrilinos copied to clipboard
Investigate IoC
The Inversion of Control in Futility is organized as follows.
User create some subroutine, for example
SUBROUTINE testcalcResid() BIND(C)
!Do some matvec
ENDSUBROUTINE testcalcResid
This function is passed through a proxy by using C_FUNLOC
:
call JFNK_Init(C_FUNLOC(testcalcResid), ...)
JFNK_Init
has the following prototype:
subroutine JFNK_Init(fptr,...) bind(C,NAME="JFNK_Init")
IMPORT :: C_FUNPTR
TYPE(C_FUNPTR),INTENT(IN),VALUE :: fptr
...
endsubroutine
with a corresponding C interfaces:
extern "C" void JFNK_Init(int &id, void (*funptr)(), const int idx,
const int idF) {
id = jfnk->new_data(funptr, evec->get_vec(idx), evec->get_vec(idF));
}
eventually ending in
class ModelEvaluator_JFNK : public NOX::Epetra::Interface::Required {
public:
ModelEvaluator_JFNK(void (*functionptr)(),Teuchos::RCP<Epetra_Vector> x, Teuchos::RCP<Epetra_Vector> F){
fptr=functionptr;
xloc=x;
Floc=F;
}
...
bool computeF(const Epetra_Vector& x,
Epetra_Vector& f,
NOX::Epetra::Interface::Required::FillType)
{
// Residual calculation
*xloc = x;
fptr();
f = *Floc;
return true;
}
private:
void (*fptr)() = NULL;
...
};