#ifndef _multiphase_rhs_
#define _multiphase_rhs_ 1
#include <alberta.h>
#include <alberta_util.h>
#include "newalberta.hh"
//#include "do_on_el.hh"
//#include "traverse.hh"
#include "operator_parts.hh"
#include "heat.hh"
#include "prototype_fem_elfunc.hh"
#include "fem_elfunc.hh"
#include "th_strain_rhs.hh"
#include "elast_problem.hh"

/*implements thermally induced strains*/
REAL th_strain_rhs::elast_rhs_th(REAL th, REAL a, REAL p, REAL m)
{
  FUNCNAME("elast_rhs_th");
  REAL alpha = a * 1.55E-5 + p * 1.70E-5 + m * 1.16E-5;
//fuers Testproblem muss alpha=1.55E-5e-5, d.h.a=1 sein!
/*    MSG("alpha = %.3le, alpha*(th-th_a) = %.3le\n",
       alpha, alpha * (th - prob_data->th_a));
*/
  return(alpha * (th -  723.0 )); // Perlit-Start-Temperatur 
}

REAL th_strain_rhs::calc(const REAL* const lambda, const int comp_dummy)
{	
	int iq=0;//hier vorlaeufig richtig
  	REAL val=0.0;
	REAL th_at_phik = eval_uh(/*&lagrangenodes[(DIM+1)*k]*/lambda ,
				(const REAL *) uh_el, temperature->fe_space->bas_fcts); 
	REAL fac1 = elast_rhs_th(th_at_phik,austenite_at_qp[iq], pearlite_at_qp[iq], 0.0/*REAL m*/);
	val = lambda3_mu2*fac1/* + lambda_mu23*fac2*/;
      return val;
}
//private! Sonst macht wer scheisse mit.
REAL th_strain_rhs::calc( const int iq, const int comp_dummy)
{
  REAL val=0.0;
	REAL fac1 = elast_rhs_th(uh_qp[iq],austenite_at_qp[iq], pearlite_at_qp[iq], 0.0/*REAL m*/);
//	REAL fac2 = elast_rhs_rho(uh_qp[iq],austenite_at_qp[iq], pearlite_at_qp[iq], 0.0/*REAL m*/);

	val = lambda3_mu2*fac1/* + lambda_mu23*fac2*/;
  return(val);
}
	

int th_strain_rhs::set_at_el(const EL_INFO * const el_info,const LAMBDA_DET* const assem_el_info)
{
   	fem_elfunc::set_at_el(el_info, assem_el_info);
	sol_bas_fcts->get_real_vec(el_info->el, temperature, uh_el);
	 uh_at_qp(quad_fast_uh, uh_el, 	uh_qp); //so!!
	return(0);
}


//void th_strain_rhs::el_fct(const EL_INFO *el_info)	
//int th_strain_rhs::calc(const EL_INFO *el_info)
 REAL th_strain_rhs::func_scp_testfunc( const int i_phi, const int j_comp)
{
	int qp, k;
	REAL scp= 0.0;
//quadratur von rhs(l):
	for (qp=0; qp < quad->n_points; qp++)
	{  
	   	REAL responseofstrain = /*th_strain_rhs::*/calc(qp,j_comp); 
		grd = 0.0;
		for (k=0; k<=el_info_ptr->mesh->dim; k++)
			grd += el_info_ptr->el_geom_cache.Lambda[k][j_comp] *
					test_quad_fast->grd_phi[qp][i_phi][k]; /*test_quad_fast u quad
					muessen gleichen Grads sein!!*/
/* th_strain_rhs::calc(qp) gibt die thermische !Dehnung! mal Diffusions (Antwort-)Matrix zurueck.
	 nicht Verschiebung. 
 grad phi also von der Testfunktion. */     
		scp += 	quad->w[qp]*el_info_ptr->el_geom_cache.det
						* responseofstrain* grd/*[j]*/;
      	} 
	return (scp);
}


th_strain_rhs::th_strain_rhs(const DOF_REAL_VEC* const   temperature
			,const  PROB_DATA_DIFF* const (prob_datas)[DIM_OF_WORLD*DIM_OF_WORLD],
					const int quad_degree)
	: 	fem_elfunc( /*quad_degree,*/ nil/*timestep*/)
		, temperature(temperature)

 {
 	FUNCNAME("th_strain_rhs constuctor");
	int l,k;
	 TEST_EXIT(temperature,"no temperature vec at the moment\n");
	 int dim = temperature->fe_space->mesh->dim, degree=quad_degree;
 	for (l=0; l<dim;l++)
	{
		for (k=0; k< dim;k++)
		{
			prob_datas_elast[l*dim+k] =  prob_datas[l*dim + k];
		}
	}
	if (quad_degree<1)
	{	degree = temperature->fe_space->bas_fcts->degree+2;
	 	MSG("quad degree reset to %d\n", degree);
	}
 	quad =  get_quadrature(dim, degree);
	sol_bas_fcts	= temperature->fe_space->bas_fcts;
   	quad_fast_uh 	= get_quad_fast(
   		sol_bas_fcts, quad, INIT_PHI);
	uh_el = new REAL [temperature->fe_space->bas_fcts->n_bas_fcts];	

	austenite_at_qp = new REAL[quad->n_points];
	pearlite_at_qp = new REAL[quad->n_points];
//	 memset(pearlite_at_qp,1,sizeof(REAL[quad->n_points])); setzt ein bit eines bytes... falsch
	for (l=0; l<quad->n_points;l++) austenite_at_qp[l] = 1.0;
	 uh_qp = new REAL[quad->n_points];
//ersma so und hier. Kann noch variabel gemacht werden.
//	REAL scale = prob_data_s11.physconstants[MU_LAMBDA_SCALE];
	REAL lambda = prob_data_s11.physconstants[LAMBDA];/*scale;*/
	REAL mu =	prob_data_s11.physconstants[MU];/*scale;*/
  lambda3_mu2 = 3.0*lambda + 2.0*mu;
  lambda_mu23 = lambda + mu*2.0/3.0;
//  lambda3_mu2 *= scale; 
//  lambda_mu23  *= scale;
MSG("constuction completed\n");
}


th_strain_rhs::~th_strain_rhs()
{

// delete [] uh_qp;
  delete [] austenite_at_qp;
  delete [] pearlite_at_qp;
//  delete [] uh_el;
// delete [] dof;
}
#endif
