#include <alberta.h>
#if (defined(ALBERTA_VER) && (ALBERTA_VER==2))
//# include <alberta_inlines.h>
//#include <alberta_util_inlines.h>
# include "alberta1_wrapper.h"
#endif
#include "newalberta.hh"
#include "prototype_fem_elfunc.hh"
#include "fem_elfunc.hh"
/*nothing componentwise here, only general and geometric things*/
int fem_elfunc::set_at_el(const EL_INFO * const el_info, REAL eval_time)
{     
	fill_el_geom_cache(el_info, FILL_EL_DET|FILL_EL_LAMBDA);
	el_info_ptr = el_info;
//	if (prob_data_ptr->f_sources)
//			prob_data_ptr->f_sources->set_at_el(el_info, nil);
			//this may do harm,... looks untidy... left to inheriting class or caller
  	return(0);
}

int fem_elfunc::set_test_quad_fast(const QUAD_FAST  *  quad_fast)
{
 	FUNCNAME("fem_elfunc::set_test_quad_fast");
	test_quad_fast = quad_fast;
	TEST_EXIT(test_quad_fast->n_points == quad->n_points
			,"quad (%d points) and test_quad_fast (%d points) misfit!\n"
				, quad->n_points, test_quad_fast->n_points);
}
//	evtl obsolet?

 REAL fem_elfunc::func_scp_testfunc( const int i_phi, const int j_comp)
{ 	//ERROR("lets see if we place <f_i_comp,phi_test_i> here\n");
	REAL val = 0.0;
	for (int qp = 0; qp < quad->n_points; qp++) 
	{
		REAL source_at_phik 
//					= common_rhs_contrib->calc( test_quad_fast->quad->lambda[qp], j);
			= calc(qp, j_comp);
			//call derived classes method (implementing func)
		val += quad->w[qp]*source_at_phik
					*test_quad_fast->phi[qp][i_phi]; //Col_phi!!
	}
	return(val*el_info_ptr->el_geom_cache.det);
};
 
 fem_elfunc::fem_elfunc(const BAS_FCTS   * const bas_fcts,  int quad_degree
						,const  REAL *const timestep):	
			prototype_fem_elfunc( bas_fcts,  quad_degree,timestep)//, test_bas_fcts(bas_fcts)
{  	 
 	quad =  get_quadrature(bas_fcts->dim, quad_degree);
    test_quad_fast = quad_fast_uh;	
    row_dof = col_dof = new DOF[test_quad_fast->n_bas_fcts]; 
    bound = new S_CHAR[test_quad_fast->n_bas_fcts]; 
}

//fuer eine Komponente
fem_elfunc::fem_elfunc(const BAS_FCTS   * const bas_fcts
				,const BAS_FCTS   * const test_bas_fcts,  int degree
				,const  REAL *const timestep):	
			prototype_fem_elfunc( bas_fcts,  degree,timestep)//, test_bas_fcts(test_bas_fcts)
{    
   FLAGS   fill_flag;
   if (test_bas_fcts->degree > 1)
     fill_flag = INIT_PHI|INIT_GRD_PHI|INIT_D2_PHI;
   else
     fill_flag = INIT_PHI|INIT_GRD_PHI;
   test_quad_fast = get_quad_fast(test_bas_fcts
	   				,quad, fill_flag);
//	   				, get_quadrature(DIM, quad_fast_uh->quad->degree), fill_flag);
	//naja
    row_dof =   new DOF[sol_bas_fcts->n_bas_fcts]; 
    if  (bas_fcts== test_bas_fcts)
    {
	 bound =	new S_CHAR[test_bas_fcts->n_bas_fcts]; 
	 col_dof = row_dof;
    }
    else
    {
	bound = nil;//muss sein, siehe Buch S. add_el_matrix 
    	col_dof =   new DOF[test_bas_fcts->n_bas_fcts];
    }
}

//Konstruktor fuer System
fem_elfunc::fem_elfunc( /* const int degree    ,*/const  REAL *const timestep)   
      :prototype_fem_elfunc( /*degree,*/ timestep)
{
/*The following things are needed to be done in each derived class:*/
#if 0
	sol_bas_fcts = phases[0] whatever ->fe_space->bas_fcts;
	if (quad_degree<1)
	{	degree = sol_bas_fcts->degree+2;
	 	MSG("quad degree reset to %d\n", degree);
	}
 	quad =  get_quadrature(dim, degree);
#endif
	/*it is an, ahem, impurity that each class derived from fem_elfunc has to do the same
	initialization of quad. But there we have no Sol DOF_REAL_VEC and such no criteria 
	for degree. Lets think of introducing 
	fem_elfunc::fem_elfunc( const int dim, const int degree    ,const  REAL *const timestep)*/
}
