Plugin with 13 parameters

Hello,
I am trying to build some C++ function to link with FreeFem++. Something like: (dummy example)

“”"
#include
using namespace std;
#include “error.hpp”
#include “AFunction.hpp”
#include “AFunction_ext.hpp”

int example(const long &n1, const long &n2, const long &n3, KN *const &vec1, KN *const &vec2, KN *const &vec3, KN *const &vec4, KN *const &vec5)
{
int M = vec2->N();
cout << "n1 : " << n1 << endl;
cout << "n2 : " << n2 << endl;
cout << "n2 : " << n3 << endl;
for (int i=0;i<M;i++) // do some stuff with some vectors
{
*(vec1[0]+i)= *(vec1[0]+i) + 1;
(vec2[0]+i)=(vec2[0]+i) * *(vec2[0]+i);
*(vec3[0]+i)= *(vec3[0]+i) - 3.;
}
return 0;
}

class Init {
public:
Init();
};

Init init;
Init::Init(){
Global.Add(“exfun”,"(",new OneOperator8_< int, long, long, long, KN, KN, KN,KN, KN* >(example));
}
“”"
but I need 13 parameters in my example function, and there is no OneOperatorX_, for X>8. How can I do it?

Thanks,
Ernesto

You could you use a KN<long> for the n[1-3] and a KN<KN<K>> for the vec[1-5]? Not ideal, but it gets. the job done.

Thanks Pierre,

but now I don’t know how to pass data to my function. If I define a
real[int,int] in .edp file to pack my vectors and use KN<KN<double>*>*
I am getting a Segment fault.

I have also tried to use a KNM<double>* and it works, but now, I don’t know how to unpack this matrix in vectors. Indeed, what I need is that every column of the matrix is a double *

Any hints?

You should be able to go from KNM<K> to KN<K> back and forth using the following syntax: FreeFem-sources/SLEPc-code.hpp at master · FreeFem/FreeFem-sources · GitHub. This sets the i th column, but should work to get it instead.

Many many thanks!!!

To the only way is to add a two class like form 13 parameter,
I think with c++20 or better you can use variadic templates , or tuples …

template<class R,class A0,class A1,class A2, class A3, class A4, class A5, class A6, class A7, class E=E_F0>   // extend AX
class E_F_F0F0F0F0F0F0F0F0_ :public  E { public:                               // extend 
   typedef  R (*func)(const  A0 &,const  A1 & , const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 & ) ; // extend AX
  func f;
  Expression a0,a1,a2,a3,a4,a5,a6,a7;          // extend aX
  E_F_F0F0F0F0F0F0F0F0_(func ff,            // extend F0
			Expression aa0,
			Expression aa1,
			Expression aa2,
			Expression aa3,
			Expression aa4,
			Expression aa5,
			Expression aa6,
			Expression aa7)   // extend 
    : f(ff), a0(aa0), a1(aa1), a2(aa2), a3(aa3), a4(aa4), a5(aa5), a6(aa6), a7(aa7) {}  // extend aX
  AnyType operator()(Stack s)  const 
    {return SetAny<R>( f( GetAny<A0>((*a0)(s)),
			  GetAny<A1>((*a1)(s)),
			  GetAny<A2>((*a2)(s)),
			  GetAny<A3>((*a3)(s)),
			  GetAny<A4>((*a4)(s)),
			  GetAny<A5>((*a5)(s)),
			  GetAny<A6>((*a6)(s)),
			  GetAny<A7>((*a7)(s)) ) );}   // extend aX
  virtual size_t nbitem() const {return a7->nbitem(); } // modif
      bool MeshIndependent() const 
      {return E::MeshIndependent() && a0->MeshIndependent() && a1->MeshIndependent()&& a2->MeshIndependent()
	 && a3->MeshIndependent()&& a4->MeshIndependent()&& a5->MeshIndependent()&& a6->MeshIndependent()&& a7->MeshIndependent();} // extend aX

};

template<class R,class A=R,class B=A,class C=B, class D=C ,class E=D ,class F=E ,class G=F ,class H=G , class CODE=E_F_F0F0F0F0F0F0F0F0_<R,A,B,C,D,E,F,G,H,E_F0> >    // extend  
class  OneOperator8_ : public OneOperator {     // 3->4
  aType r; //  return type 
    typedef typename  CODE::func  func;
  func f;
public: 
  E_F0 * code(const basicAC_F0 & args) const 
    {  
	if ( args.named_parameter && !args.named_parameter->empty()  ) 
	    CompileError( " They are used Named parameter ");
	
	return  new CODE(f,
		     t[0]->CastTo(args[0]),
		     t[1]->CastTo(args[1]),
		     t[2]->CastTo(args[2]),
		     t[3]->CastTo(args[3]),
		     t[4]->CastTo(args[4]),
		     t[5]->CastTo(args[5]),
		     t[6]->CastTo(args[6]),
		     t[7]->CastTo(args[7]));}     // extend
  OneOperator8_(func  ff):                        // 3->4
    OneOperator(map_type[typeid(R).name()],
		map_type[typeid(A).name()],
		map_type[typeid(B).name()],
		map_type[typeid(C).name()],
		map_type[typeid(D).name()],
		map_type[typeid(E).name()],
		map_type[typeid(F).name()],
		map_type[typeid(G).name()],
		map_type[typeid(H).name()]),      // extend
    f(ff){}
};