#ifndef _elast_problem_
#define _elast_problem_ 1
#include <alberta.h>
#include <alberta_util.h>
#include "newalberta.hh"
#include "prototype_fem_elfunc.hh"
#include "fem_elfunc.hh"
#include "operator_parts.hh"
#include "elast.hh"
#include "elast_problem.hh"

const  PROB_DATA_DIFF* /*const*/ (prob_datas_elast)[DIM*DIM];
//nix allokiert bis jetzt!

const_full_mat::const_full_mat(REAL* coeffs): constmat(0.0)
{int i,j;
for (i=0; i< DIM; i++)
	for (j=0; j< DIM; j++)
		mat[i][j] = coeffs[i*DIM+j]; 
}

/*d dfpoly/ d phi1, dfpoly>0 auf dem Gibbschen Simplex,modelliert Wachstum von phi_1 (Perlit) 
							falls delta G:= G_1 - G_2 <0 */
//ist Funktionalableitung von -(phi1-phi2)^3/3 +phi1 - phi2
//Driving Force Polynom f. die wachsende Phase
#if 0
REAL ddfpoly(REAL phi1, REAL phi2)
{
	REAL val = 	- pow(phi1 - phi2, 2.0) + 1;
	return(val);
}
#endif
static REAL gu_D_ou(const REAL_D x, REAL t)
{
  return(0.01*x[1]);
}

static REAL gu_D_lr(const REAL_D x, REAL t)
{
  return(0.0);
}

static REAL gu_N_0(const REAL_D x, REAL t, S_CHAR bound)
{
  
  return(0.0);
}
#if 0
Unsinn
static REAL gu_N_ou(const REAL_D x, REAL t, S_CHAR bound)
{
  
  return(0.0);
}
#endif


#if 0
//Symmetr. Matrizen: Zeile p , pp, ap, aa, a 
//das muss dann effektiv positiv definit werden 
//mal gucken. Ist vielleicht ueberfluessig
#endif




 /* REAL         mu;
  REAL         lambda;
  REAL         mu_lambda_scale;

  REAL         rho;
*/

//Sieben Instanzen fuer prob_data der isotropen Antwortmatrix., reichen fuer ein Problem, in dem 2 Phasen vorkommen 
//mit rhs u. ggf mit ex_sols befuellen.
//Austenit-Diag
PROB_DATA_DIFF prob_data_s11 =
 {
	   nil, nil,        /* diffkoeff(=alpha), order0 werden ueberschrieben!!*/
	   nil		//massfunc
	   , 0  		//constflag
	,{    0.6882, 1.0724, 1.0E11,   /* my, lambda, mu_lambda_scale*/
  		  7659.0,                   /* rho */
		 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
		},
	nil/*dw_rhs_aa*/,
        nil, gu_D_lr, gu_N_0,		// ex_sol	
        nil, nil /* ph_ex, grd_ph_ex */
 };

PROB_DATA_DIFF prob_data_s22 =
 {
	   nil, nil,        /* diffkoeff(=alpha), order0 werden ueberschrieben!!*/
	   nil		//massfunc
	   , 0 		//constflag
	,{    0.6882, 1.0724, 1.0E11,   /* my, lambda, mu_lambda_scale*/
 		   7659.0,                   /* rho */
		 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
		},
	nil/*dw_rhs_aa*/,
        nil, gu_D_ou, nil/*gu_N_ou*/,		// Dehnung in y-Richtung auf Rand vorgegeben
        nil, nil /* ph_ex, grd_ph_ex */
 };

PROB_DATA_DIFF prob_data_s33 =
 {
	   nil, nil,        /* diffkoeff(=alpha), order0 werden ueberschrieben!!*/
	   nil		//massfunc
	   , 0		//constflag
	,{    0.6882, 1.0724, 1.0E11,   /* my, lambda, mu_lambda_scale*/
   		 7659.0,                   /* rho */
		 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
		},
	nil,					//Nebendiagonal-Prob_Data hat keine eigene RHS,
        nil, gu_D_lr, gu_N_0,	/*keine exakte Loesung u hom. Neumann- Randdaten(
<=> kein Beitrag. Sinngemaess was andres als gDph_0,  gNph_0, aber gleiche Werte erforderlich.).*/
        nil, nil /* ph_ex, grd_ph_ex */
 };

PROB_DATA_DIFF prob_data_s12 =
 {
 	   nil, nil,        /* diffkoeff(=alpha), order0 werden ueberschrieben!!*/
	   nil		//massfunc
	   , 0		//constflag
	,{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
		},
	nil,					//Nebendiagonal-Prob_Data hat keine eigene RHS,
        nil, nil,  nil,	
	        nil, nil 
 };

PROB_DATA_DIFF prob_data_s13 =
 {
 	   nil, nil,        /* diffkoeff(=alpha), order0 werden ueberschrieben!!*/
	   nil		//massfunc
	   , 0		//constflag
	,{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
		},
	nil,					//Nebendiagonal-Prob_Data hat keine eigene RHS,
        nil, nil,  nil,	
        nil, nil /* ph_ex, grd_ph_ex */
 };

PROB_DATA_DIFF prob_data_s23 =
 {
	   nil, nil,        /* diffkoeff(=alpha), order0 werden ueberschrieben!!*/
	   nil		//massfunc
	   , 0		//constflag
	,{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
		},
	nil,
        nil , nil, nil,
        nil, nil /* ph_ex, grd_ph_ex */
 };
//Perlit-Perlit Kopplung
PROB_DATA_DIFF prob_data_s21 =
 {
	   nil, nil,        /* diffkoeff(=alpha), order0 werden ueberschrieben!!*/
	   nil		//massfunc
	   , 0		//constflag
	,{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
		},
	nil,
        nil , nil, nil,
        nil, nil /* ph_ex, grd_ph_ex */
 };
PROB_DATA_DIFF prob_data_s31 =
 {
	   nil, nil,        /* diffkoeff(=alpha), order0 werden ueberschrieben!!*/
	   nil		//massfunc
	   , 0		//constflag
	,{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
		},
	nil,
        nil , nil, nil,
        nil, nil /* ph_ex, grd_ph_ex */
 };
PROB_DATA_DIFF prob_data_s32 =
 {
	   nil, nil,        /* diffkoeff(=alpha), order0 werden ueberschrieben!!*/
	   nil		//massfunc
	   , 0		//constflag
	,{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
		},
	nil/*dw_rhs_pp*/,
        nil , nil, nil,//ph1_0= 1 - ph0_0//klappte mit ph10_0
        nil, nil /* ph_ex, grd_ph_ex */
 };


 void init_problem_standard_steel()
{
  FUNCNAME("init_problem_standard_steel");
//	int i,j;
	REAL scale = 1; //prob_data_s11.physconstants[MU_LAMBDA_SCALE];
	REAL lambda = prob_data_s11.physconstants[LAMBDA]*scale;
	REAL mu =	prob_data_s11.physconstants[MU]*scale;
	REAL response_block[DIM*DIM];
//  prob_data_s11.f_sources = new rhs_th_ph_rho(0, -beta_ap[4]);//(0, beta_ap[4]);eigentl. doch ok?
 // prob_data_s22.f_sources = new dw_rhs_2ph_general(1, beta_ap[4]);//(1, -beta_ap[4]);



  REAL lambdaplus2mu	= lambda + 2.0*mu ;

//Blockmatrizen der Antwortfkt berechnen
  memset(&response_block, 0, sizeof(REAL[DIM*DIM]));
  response_block[0] = lambdaplus2mu;
  response_block[DIM+1] = mu;
  if (DIM==3)   response_block[2*DIM+2] = mu;

  prob_data_s11.diffmat 	= new const_full_mat(response_block);

  memset(&response_block, 0, sizeof(REAL[DIM*DIM]));
  response_block[0] 	= mu;
  response_block[DIM+1] = lambdaplus2mu;
  if (DIM==3)   response_block[2*DIM+2] = mu;
  prob_data_s22.diffmat 	= new const_full_mat(response_block);
  if (DIM==3)
  {
	memset(&response_block, 0, sizeof(REAL[DIM*DIM]));
	response_block[0] 	= mu;
	response_block[DIM+1] = mu;
	response_block[2*DIM+2] = lambdaplus2mu;
 	prob_data_s33.diffmat 	= new const_full_mat(response_block);
   }
  memset(&response_block, 0, sizeof(REAL[DIM*DIM]));
  response_block[1] 	= lambda;
  response_block[DIM] = mu;
  prob_data_s12.diffmat 	= new const_full_mat(response_block);
//notwendig??
  response_block[1] 	= mu;
  response_block[DIM] 	= lambda;
  prob_data_s21.diffmat 	= new const_full_mat(response_block);
  if (DIM==3)
  {
  	memset(&response_block, 0, sizeof(REAL[DIM*DIM]));
  	response_block[2] 	= lambda;
  	response_block[2*DIM] = mu;
  	prob_data_s13.diffmat 	= new const_full_mat(response_block);
//notwendig??
	response_block[2] 	= mu;
	response_block[2*DIM] 	= lambda;
	prob_data_s31.diffmat 	= new const_full_mat(response_block);

  	memset(&response_block, 0, sizeof(REAL[DIM*DIM]));
  	response_block[2*DIM -1]= lambda;
  	response_block[2*DIM+1] = mu;
  	prob_data_s23.diffmat 	= new const_full_mat(response_block);
//notwendig??
  	response_block[2*DIM -1]   = mu;
  	response_block[2*DIM+1]    = lambda;
	prob_data_s32.diffmat 	= new const_full_mat(response_block);
   }
  prob_data_s11.flags =  prob_data_s22.flags = prob_data_s33.flags 
  = prob_data_s21.flags =  prob_data_s32.flags = prob_data_s31.flags 
 	= prob_data_s12.flags = prob_data_s13.flags = prob_data_s23.flags =DIFFMAT_PW_CONST | DIFFMAT_FULL; 
//   prob_data..flags= DIFFMAT_PW_CONST;
}

/*berechnet den Index eines Elementes einer als Vektor abgespeicherten Symmetrischen Matrix
z.B
0 1 2  3  
  4 5  6
    7  8  
       9 
   */
#endif
