/*!de facto abstract base class of everything that deals with a possibly time dependant
fem solution (umplemented by u_h and u_old), traversing a mesh. At this time this is the
 build branch and the estimate branch. */		
// fem_base enthaelt alle Daten des Problems
// gemeinsamer Nenner aller Methoden, die eine FEM_Loesung einer DGL verarbeiten.
class fem_base: public do_elfunc_on_el
{
public:

DOF_REAL_VEC* get_sol(int row) const
  { 
    FUNCNAME("get_sol");
    TEST_EXIT(row <=ncomps, "%s comps %d called, which is bigger than ncomps\n", u_h[0]->name,row);
    return((DOF_REAL_VEC *const)u_h[row]);
  };
DOF_REAL_VEC* get_sol() const
  {
    return((DOF_REAL_VEC*)u_h[0]);
  };
DOF_REAL_VEC *get_old_sol(int row) const
  { 
    FUNCNAME("get_old_sol");
    TEST_EXIT(row <=ncomps, "%s comps %d called, which is bigger than ncomps\n", u_old[0]->name,row);
    return((DOF_REAL_VEC *const)u_old[row]);
  }; 
DOF_REAL_VEC *get_old_sol(void) const
  {
    return((DOF_REAL_VEC*)u_old[0]);
  }; 
DOF_SCHAR_VEC  * get_bound_vec(int row) const
  { 
    FUNCNAME("get_sol");
    TEST_EXIT(row <=ncomps, "%s comps %d  called, which is bigger than ncomps\n"
    	, bound_vec[0]->name,row);
    return((DOF_SCHAR_VEC *const)bound_vec[row]);
  };
DOF_SCHAR_VEC  * get_bound_vec() const
  {
    return((DOF_SCHAR_VEC*)bound_vec[0]);
  };

  void init_timestep();

protected:
  int	          info_level;     //for INFO macro use
  const int ncomps;
  DOF_REAL_VEC   **u_h;
  DOF_REAL_VEC   **u_old;
  DOF_SCHAR_VEC  **bound_vec;	/* ist aber erst ein anfang. Sollte spaeter als Haupt-InfoTraeger
								bez. Rand fungieren*/
  REAL      const   * const time;
  fem_elfunc*  common_source_contrib;
//  public_do_elfunc_on_el *  common_source_contrib;
  //rhs contribution to all ncomps. Useful if contibutions need to calculate complicated expressions,
  //this means those depending on some uh, test functions and integration.
  //which are used in each u_h component. PROB_DATA_DIFF. source is added, though, but not here.
/*the definition as fem_elfunc is thus preferred against definition as prototype_fem_elfunc. 
Mind that this is a pointer! Therre is an error here if the same quad_fast is used during assemblage
 and estimation!*/
  OP_ARG_INFO **op_arg_infos;
  OP_ARG_INFO *op_arg_info;
//neu Baustelle
//dies viell. nach  prototype_fem elfunc oder wall_fem_elfunc schreiben?
  const WALL_QUAD_FAST *wall_quad_fast; /* wall integration */

public:
//copy-Konstruktor
/*for creating an estimator from a build_...
Bad thing is that this constructor copies common_source_contrib , including its quads, which need not be the same
for estimation and assemblage. So we should pay attention not to use them!*/
  fem_base(const fem_base& base_to_copy)
    : info_level(base_to_copy.info_level),
        ncomps(base_to_copy.ncomps),
     u_h(base_to_copy.u_h),
      u_old(base_to_copy.u_old),
      bound_vec(base_to_copy.bound_vec),  
       time(base_to_copy.time),
       common_source_contrib(base_to_copy.common_source_contrib), //Fehler! Pointer wird kopiert, Quad_fast
       			//stimmt aber nicht fuer Schaetzer! Baustelle!
      op_arg_infos(base_to_copy.op_arg_infos)  //diskutabel
      	{    op_arg_info = op_arg_infos[0];//new OP_ARG_INFO(base_to_copy.op_arg_info->prob_data_ptr))
//		TEST_EXIT(,"\n");
	};

  fem_base(const char *const name,
	   DOF_REAL_VEC **u_h, DOF_REAL_VEC **u_h_old, DOF_SCHAR_VEC** bound_vec,
	   const PROB_DATA_DIFF * const * const prob_data, const int ncomps
	   , REAL const   * const time);
//der muss mal so langsam zu den Akten:
  fem_base(const char *const name,  FE_SPACE const *const fe_space,
	   const PROB_DATA_DIFF *const * const prob_data, const int ncomps, REAL  const   * const time);
	~fem_base()
		{//muss noch
		}
//Dummies u. fast-dummies. An sich ist fem_base eine abstrakte Klasse, es sollte keine
//Instanzen geben, zumindest keine langlebigen. Nur vererbte

   virtual  int set_at_el(const EL_INFO * const el_info, REAL eval_time)
		{FUNCNAME("fem_base::set_at_el");
		ERROR_EXIT("unimplemented Method");
		return(1);
		};
	/*Dummy*/
  virtual REAL calc(const REAL*)
		{FUNCNAME("fem_base::calc(const REAL*)");
		ERROR_EXIT("unimplemented Method");
		return(0.0);
		};
		/*Dummy*/
  virtual REAL calc(const int)
		{FUNCNAME("fem_base::calc(const int)");
		ERROR_EXIT("unimplemented Method");
		return(0.0);
		};
		/*Dummy*/
  virtual int calc(const EL_INFO*)
		{FUNCNAME("fem_base::calc(const EL_INFO*)");
		ERROR_EXIT("unimplemented Method");
		return(0);
		};
};

