/*!\file Penpair.c
 * \brief: implementation of the Penpair 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 "./Penpair.h"
#include <string.h>
#include "../EnumDefinitions/EnumDefinitions.h"
#include "../shared/shared.h"
#include "../include/typedefs.h"

		
Penpair::Penpair(){
	return;
}

Penpair::Penpair(int	penpair_id, double penpair_penalty_offset,int  penpair_penalty_lock,int penpair_numdofs,int penpair_node_ids[2],int penpair_dof,
		int penpair_element_ids[2],double penpair_friction,int penpair_fill,double penpair_normal[2],double penpair_length){
	
	int i;
	id=penpair_id;
	penalty_offset =penpair_penalty_offset;
	penalty_lock  =penpair_penalty_lock;
	numdofs =penpair_numdofs;

	for(i=0;i<2;i++){
		node_ids[i]=penpair_node_ids[i];
		node_offsets[i]=UNDEF;
		nodes[i]=NULL;

		element_ids[i]=penpair_element_ids[i];
		element_offsets[i]=UNDEF;
		elements[i]=NULL;
	}
	dof=penpair_dof;
	
	friction =penpair_friction;
	fill =penpair_fill;
	normal[0]=penpair_normal[0];
	normal[1]=penpair_normal[1];
	length=penpair_length;

	return;
}

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

	int i;

	printf("Penpair:\n");
	printf("   id: %i\n",id);
	printf("   penalty_offset: %g\n",penalty_offset);
	printf("   penalty_lock: %i\n",penalty_lock);
	printf("   numdofs: %i\n",numdofs);
	printf("   node_ids: [%i %i]\n",node_ids[0],node_ids[1]);
	printf("   node_offsets: [%i %i]\n",node_offsets[0],node_offsets[1]);
	printf("   dof: %i\n",dof);
	printf("   element_ids: [%i %i]\n",element_ids[0],element_ids[1]);
	printf("   element_offsets: [%i %i]\n",element_offsets[0],element_offsets[1]);
	printf("   friction: %g\n",friction);
	printf("   fill: %i\n",fill);
	printf("   normal: %g %g\n",normal[0],normal[1]);
	printf("   length: %g\n",length);
	
	for(i=0;i<2;i++){
		if(nodes[i])nodes[i]->Echo();
		if(elements[i])elements[i]->Echo();
	}
	return;
}
		
void  Penpair::Marshall(char** pmarshalled_dataset){

	char* marshalled_dataset=NULL;
	int   enum_type=0;

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

	/*get enum type of Penpair: */
	enum_type=PenpairEnum();
	
	/*marshall enum: */
	memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type);
	
	/*marshall Penpair data: */
	memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id);
	memcpy(marshalled_dataset,&penalty_offset,sizeof(penalty_offset));marshalled_dataset+=sizeof(penalty_offset);
	memcpy(marshalled_dataset,&penalty_lock,sizeof(penalty_lock));marshalled_dataset+=sizeof(penalty_lock);
	memcpy(marshalled_dataset,&numdofs,sizeof(numdofs));marshalled_dataset+=sizeof(numdofs);
	memcpy(marshalled_dataset,&dof,sizeof(dof));marshalled_dataset+=sizeof(dof);
	memcpy(marshalled_dataset,&node_ids,sizeof(node_ids));marshalled_dataset+=sizeof(node_ids);
	memcpy(marshalled_dataset,&node_offsets,sizeof(node_offsets));marshalled_dataset+=sizeof(node_offsets);
	memcpy(marshalled_dataset,&element_ids,sizeof(element_ids));marshalled_dataset+=sizeof(element_ids);
	memcpy(marshalled_dataset,&element_offsets,sizeof(element_offsets));marshalled_dataset+=sizeof(element_offsets);
	memcpy(marshalled_dataset,&friction,sizeof(friction));marshalled_dataset+=sizeof(friction);
	memcpy(marshalled_dataset,&fill,sizeof(fill));marshalled_dataset+=sizeof(fill);
	memcpy(marshalled_dataset,&normal,sizeof(normal));marshalled_dataset+=sizeof(normal);
	memcpy(marshalled_dataset,&length,sizeof(length));marshalled_dataset+=sizeof(length);

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

	return sizeof(id)+
		sizeof(penalty_offset)+
		sizeof(penalty_lock)+
		sizeof(numdofs)+
		sizeof(dof)+
		sizeof(node_ids)+
		sizeof(node_offsets)+
		sizeof(element_ids)+
		sizeof(element_offsets)+
		sizeof(friction)+
		sizeof(fill)+
		sizeof(normal)+
		sizeof(length)+
		sizeof(int); //sizeof(int) for enum type
}

char* Penpair::GetName(void){
	return "penpair";
}
		

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

	int i;
	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(&id,marshalled_dataset,sizeof(id));marshalled_dataset+=sizeof(id);
	memcpy(&penalty_offset,marshalled_dataset,sizeof(penalty_offset));marshalled_dataset+=sizeof(penalty_offset);
	memcpy(&penalty_lock,marshalled_dataset,sizeof(penalty_lock));marshalled_dataset+=sizeof(penalty_lock);
	memcpy(&numdofs,marshalled_dataset,sizeof(numdofs));marshalled_dataset+=sizeof(numdofs);
	memcpy(&dof,marshalled_dataset,sizeof(dof));marshalled_dataset+=sizeof(dof);
	memcpy(&node_ids,marshalled_dataset,sizeof(node_ids));marshalled_dataset+=sizeof(node_ids);
	memcpy(&node_offsets,marshalled_dataset,sizeof(node_offsets));marshalled_dataset+=sizeof(node_offsets);
	memcpy(&element_ids,marshalled_dataset,sizeof(element_ids));marshalled_dataset+=sizeof(element_ids);
	memcpy(&element_offsets,marshalled_dataset,sizeof(element_offsets));marshalled_dataset+=sizeof(element_offsets);
	memcpy(&friction,marshalled_dataset,sizeof(friction));marshalled_dataset+=sizeof(friction);
	memcpy(&fill,marshalled_dataset,sizeof(fill));marshalled_dataset+=sizeof(fill);
	memcpy(&normal,marshalled_dataset,sizeof(normal));marshalled_dataset+=sizeof(normal);
	memcpy(&length,marshalled_dataset,sizeof(length));marshalled_dataset+=sizeof(length);

	for(i=0;i<2;i++){
		elements[i]=NULL;
		nodes[i]=NULL;
	}

	/*return: */
	*pmarshalled_dataset=marshalled_dataset;
	return;
}
int Penpair::Enum(void){

	return PenpairEnum();
}

int    Penpair::GetId(void){ return id; }

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

#undef __FUNCT__ 
#define __FUNCT__ "Penpair::Configure"

void  Penpair::Configure(void* pelementsin,void* pnodesin,void* pmaterialsin){

	DataSet* elementsin=NULL;
	DataSet* nodesin=NULL;

	/*Recover pointers :*/
	elementsin=(DataSet*)pelementsin;
	nodesin=(DataSet*)pnodesin;
printf("here1\n");	
	/*Link this load with its nodes: */
	ResolvePointers((Object**)nodes,node_ids,node_offsets,2,nodesin);
printf("here2\n");	

	/*Same for elements: */
	ResolvePointers((Object**)&elements,element_ids,element_offsets,2,elementsin);
printf("here3\n");	

}


#undef __FUNCT__ 
#define __FUNCT__ "Penpair::CreateKMatrix"

void  Penpair::CreateKMatrix(Mat Kgg,ParameterInputs* inputs,int analysis_type){

	/*No loads applied, do nothing: */
	return;

}

#undef __FUNCT__ 
#define __FUNCT__ "Penpair::CreatePVector"
void  Penpair::CreatePVector(Vec pg, ParameterInputs* inputs, int analysis_type){

	/*No loads applied, do nothing: */
	return;

}
#undef __FUNCT__ 
#define __FUNCT__ "Penpair::UpdateFromInputs"
void  Penpair::UpdateFromInputs(ParameterInputs* inputs){
	
}

#undef __FUNCT__ 
#define __FUNCT__ "Penpair::PenaltyCreateKMatrix"
void  Penpair::PenaltyCreateKMatrix(Mat Kgg,ParameterInputs* inputs,double kmax,int analysis_type){
	throw ErrorException(__FUNCT__," not implemented yet!");
}
		
#undef __FUNCT__ 
#define __FUNCT__ "Penpair::PenaltyCreatePVector"
void  Penpair::PenaltyCreatePVector(Vec pg,ParameterInputs* inputs,double kmax,int analysis_type){
	throw ErrorException(__FUNCT__," not implemented yet!");
}

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

