/*!\file Matpar.c
 * \brief: implementation of the Matpar object
 */


#ifdef HAVE_CONFIG_H
	#include "config.h"
#else
#error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
#endif

#include "stdio.h"
#include "../shared/shared.h"
#include "./Matpar.h"
#include <string.h>
#include "../EnumDefinitions/EnumDefinitions.h"

		
Matpar::Matpar(){
	return;
}
Matpar::Matpar(int	matpar_mid, double	matpar_rho_ice, double	matpar_rho_water, double  matpar_heatcapacity, double  matpar_thermalconductivity, double  matpar_latentheat, double  matpar_beta, double  matpar_meltingpoint, double  matpar_mixed_layer_capacity, double  matpar_thermal_exchange_velocity, double  matpar_g, double  matpar_viscosity_overshoot){


	mid=matpar_mid; 
	rho_ice=matpar_rho_ice; 
	rho_water=matpar_rho_water; 
	heatcapacity=matpar_heatcapacity; 
	thermalconductivity=matpar_thermalconductivity; 
	latentheat=matpar_latentheat; 
	beta=matpar_beta; 
	meltingpoint=matpar_meltingpoint; 
	mixed_layer_capacity=matpar_mixed_layer_capacity; 
	thermal_exchange_velocity=matpar_thermal_exchange_velocity; 
	g=matpar_g; 
	viscosity_overshoot=matpar_viscosity_overshoot;

	return;
}

Matpar::~Matpar(){
	return;
}
void Matpar::Echo(void){

	printf("Matpar:\n");
	printf("   mid: %i\n",mid);
	printf("   rho_ice: %g\n",rho_ice);
	printf("   rho_water: %g\n",rho_water);
	printf("   heatcapacity: %g\n",heatcapacity);
	printf("   thermalconductivity: %g\n",thermalconductivity);
	printf("   latentheat: %g\n",latentheat);
	printf("   beta: %g\n",beta);
	printf("   meltingpoint: %g\n",meltingpoint);
	printf("   mixed_layer_capacity: %g\n",mixed_layer_capacity);
	printf("   thermal_exchange_velocity: %g\n",thermal_exchange_velocity);
	printf("   g: %g\n",g);
	printf("   viscosity_overshoot: %g\n",viscosity_overshoot);
	return;
}
		
void  Matpar::Marshall(char** pmarshalled_dataset){

	char* marshalled_dataset=NULL;
	int   enum_type=0;

	/*recover marshalled_dataset: */
	marshalled_dataset=*pmarshalled_dataset;

	/*get enum type of Matpar: */
	enum_type=MatparEnum();
	
	/*marshall enum: */
	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
	
	/*marshall Matpar data: */
	memcpy(marshalled_dataset,&mid,sizeof(mid));marshalled_dataset+=sizeof(mid);
	memcpy(marshalled_dataset,&rho_ice,sizeof(rho_ice));marshalled_dataset+=sizeof(rho_ice);
	memcpy(marshalled_dataset,&rho_water,sizeof(rho_water));marshalled_dataset+=sizeof(rho_water);
	memcpy(marshalled_dataset,&heatcapacity,sizeof(heatcapacity));marshalled_dataset+=sizeof(heatcapacity);
	memcpy(marshalled_dataset,&thermalconductivity,sizeof(thermalconductivity));marshalled_dataset+=sizeof(thermalconductivity);
	memcpy(marshalled_dataset,&latentheat,sizeof(latentheat));marshalled_dataset+=sizeof(latentheat);
	memcpy(marshalled_dataset,&beta,sizeof(beta));marshalled_dataset+=sizeof(beta);
	memcpy(marshalled_dataset,&meltingpoint,sizeof(meltingpoint));marshalled_dataset+=sizeof(meltingpoint);
	memcpy(marshalled_dataset,&mixed_layer_capacity,sizeof(mixed_layer_capacity));marshalled_dataset+=sizeof(mixed_layer_capacity);
	memcpy(marshalled_dataset,&thermal_exchange_velocity,sizeof(thermal_exchange_velocity));marshalled_dataset+=sizeof(thermal_exchange_velocity);
	memcpy(marshalled_dataset,&g,sizeof(g));marshalled_dataset+=sizeof(g);
	memcpy(marshalled_dataset,&viscosity_overshoot,sizeof(viscosity_overshoot));marshalled_dataset+=sizeof(viscosity_overshoot);

	*pmarshalled_dataset=marshalled_dataset;
	return;
}
		
int   Matpar::MarshallSize(){

	return sizeof(mid)+
		sizeof(rho_ice)+
		sizeof(rho_water)+
		sizeof(heatcapacity)+
		sizeof(thermalconductivity)+
		sizeof(latentheat)+
		sizeof(beta)+
		sizeof(meltingpoint)+
		sizeof(mixed_layer_capacity)+
		sizeof(thermal_exchange_velocity)+
		sizeof(g)+
		sizeof(viscosity_overshoot)+
		sizeof(int); //sizeof(int) for enum type
}

char* Matpar::GetName(void){
	return "matpar";
}
		

void  Matpar::Demarshall(char** pmarshalled_dataset){

	char* marshalled_dataset=NULL;

	/*recover marshalled_dataset: */
	marshalled_dataset=*pmarshalled_dataset;

	/*this time, no need to get enum type, the pointer directly points to the beginning of the 
	 *object data (thanks to DataSet::Demarshall):*/

	memcpy(&mid,marshalled_dataset,sizeof(mid));marshalled_dataset+=sizeof(mid);
	memcpy(&rho_ice,marshalled_dataset,sizeof(rho_ice));marshalled_dataset+=sizeof(rho_ice);
	memcpy(&rho_water,marshalled_dataset,sizeof(rho_water));marshalled_dataset+=sizeof(rho_water);
	memcpy(&heatcapacity,marshalled_dataset,sizeof(heatcapacity));marshalled_dataset+=sizeof(heatcapacity);
	memcpy(&thermalconductivity,marshalled_dataset,sizeof(thermalconductivity));marshalled_dataset+=sizeof(thermalconductivity);
	memcpy(&latentheat,marshalled_dataset,sizeof(latentheat));marshalled_dataset+=sizeof(latentheat);
	memcpy(&beta,marshalled_dataset,sizeof(beta));marshalled_dataset+=sizeof(beta);
	memcpy(&meltingpoint,marshalled_dataset,sizeof(meltingpoint));marshalled_dataset+=sizeof(meltingpoint);
	memcpy(&mixed_layer_capacity,marshalled_dataset,sizeof(mixed_layer_capacity));marshalled_dataset+=sizeof(mixed_layer_capacity);
	memcpy(&thermal_exchange_velocity,marshalled_dataset,sizeof(thermal_exchange_velocity));marshalled_dataset+=sizeof(thermal_exchange_velocity);
	memcpy(&g,marshalled_dataset,sizeof(g));marshalled_dataset+=sizeof(g);
	memcpy(&viscosity_overshoot,marshalled_dataset,sizeof(viscosity_overshoot));marshalled_dataset+=sizeof(viscosity_overshoot);

	/*return: */
	*pmarshalled_dataset=marshalled_dataset;
	return;
}

int Matpar::Enum(void){

	return MatparEnum();

}

int    Matpar::GetId(void){ return mid; }

int    Matpar::MyRank(void){ 
	extern int my_rank;
	return my_rank; 
}
void  Matpar::DistributeNumDofs(int* numdofspernode,int analysis_type){return;}

#undef __FUNCT__ 
#define __FUNCT__ "Matpar::UpdateFromInputs"
void  Matpar::UpdateFromInputs(ParameterInputs* inputs){
	
	throw ErrorException(__FUNCT__," not supported yet!");

}

double Matpar::GetG(){
	return g;
}
double Matpar::GetRhoIce(){
	return rho_ice;
}
double Matpar::GetRhoWater(){
	return rho_water;
}

Object* Matpar::copy() {
	return new Matpar(*this); 
}
