/*!\file PetscVecExternalResult.c * \brief: implementation of the PetscVecExternalResult object */ /*header files: */ /*{{{1*/ #ifdef HAVE_CONFIG_H #include #else #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!" #endif #include #include #include "../objects.h" #include "../../EnumDefinitions/EnumDefinitions.h" #include "../../shared/shared.h" #include "../../Container/Container.h" #include "../../include/include.h" /*}}}*/ /*PetscVecExternalResult constructors and destructor*/ /*FUNCTION PetscVecExternalResult::PetscVecExternalResult(){{{1*/ PetscVecExternalResult::PetscVecExternalResult(){ return; } /*}}}*/ /*FUNCTION PetscVecExternalResult::PetscVecExternalResult(int enum_type,IssmPetscVec value){{{1*/ PetscVecExternalResult::PetscVecExternalResult(int in_id, int in_enum_type,Vector* in_value,int in_step, double in_time){ id=in_id; enum_type=in_enum_type; value=NULL; if(in_value){ value=in_value->Duplicate(); in_value->Copy(value); } else value=NULL; step=in_step; time=in_time; } /*}}}*/ /*FUNCTION PetscVecExternalResult::~PetscVecExternalResult(){{{1*/ PetscVecExternalResult::~PetscVecExternalResult(){ VecFree(&value); } /*}}}*/ /*Object virtual functions definitions:*/ /*FUNCTION PetscVecExternalResult::Echo {{{1*/ void PetscVecExternalResult::Echo(void){ printf("PetscVecExternalResult:\n"); printf(" enum: %i (%s)\n",this->enum_type,EnumToStringx(this->enum_type)); } /*}}}*/ /*FUNCTION PetscVecExternalResult::DeepEcho{{{1*/ void PetscVecExternalResult::DeepEcho(void){ int i; printf("PetscVecExternalResult:\n"); printf(" id: %i\n",this->id); printf(" enum: %i (%s)\n",this->enum_type,EnumToStringx(this->enum_type)); printf(" step: %i\n",this->step); printf(" time: %g\n",this->time); VecView(value,PETSC_VIEWER_STDOUT_WORLD); } /*}}}*/ /*FUNCTION PetscVecExternalResult::Id{{{1*/ int PetscVecExternalResult::Id(void){ return -1; } /*}}}*/ /*FUNCTION PetscVecExternalResult::MyRank{{{1*/ int PetscVecExternalResult::MyRank(void){ extern int my_rank; return my_rank; } /*}}}*/ #ifdef _SERIAL_ /*FUNCTION PetscVecExternalResult::Marshall{{{1*/ void PetscVecExternalResult::Marshall(char** pmarshalled_dataset){ char* marshalled_dataset=NULL; int enum_value=0; int M; double* serial_value=NULL; /*recover marshalled_dataset: */ marshalled_dataset=*pmarshalled_dataset; /*get enum value of PetscVecExternalResult: */ enum_value=PetscVecExternalResultEnum; /*marshall enum: */ memcpy(marshalled_dataset,&enum_value,sizeof(enum_value));marshalled_dataset+=sizeof(enum_value); /*marshall PetscVecExternalResult data: */ memcpy(marshalled_dataset,&id,sizeof(id));marshalled_dataset+=sizeof(id); memcpy(marshalled_dataset,&enum_type,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type); memcpy(marshalled_dataset,&step,sizeof(step));marshalled_dataset+=sizeof(step); memcpy(marshalled_dataset,&time,sizeof(time));marshalled_dataset+=sizeof(time); if(value){ VecGetSize(value,&M); VecToMPISerial(&serial_value,value); memcpy(marshalled_dataset,&M,sizeof(M));marshalled_dataset+=sizeof(M); memcpy(marshalled_dataset,serial_value,M*sizeof(double));marshalled_dataset+=(M*sizeof(double)); } else{ M=0; memcpy(marshalled_dataset,&M,sizeof(M));marshalled_dataset+=sizeof(M); } /*Free ressources:*/ xfree((void**)&serial_value); /*return:*/ *pmarshalled_dataset=marshalled_dataset; } /*}}}*/ /*FUNCTION PetscVecExternalResult::MarshallSize{{{1*/ int PetscVecExternalResult::MarshallSize(){ int M=0; if(value)VecGetSize(value,&M); return sizeof(M)+M*sizeof(double) +sizeof(id) +sizeof(enum_type) +sizeof(step) +sizeof(time) +sizeof(int); //sizeof(int) for enum value } /*}}}*/ /*FUNCTION PetscVecExternalResult::Demarshall{{{1*/ void PetscVecExternalResult::Demarshall(char** pmarshalled_dataset){ char* marshalled_dataset=NULL; int i; int M; double* serial_vec=NULL; int* idxm=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(&enum_type,marshalled_dataset,sizeof(enum_type));marshalled_dataset+=sizeof(enum_type); /*data: */ memcpy(&step,marshalled_dataset,sizeof(step));marshalled_dataset+=sizeof(step); memcpy(&time,marshalled_dataset,sizeof(time));marshalled_dataset+=sizeof(time); memcpy(&M,marshalled_dataset,sizeof(M));marshalled_dataset+=sizeof(M); if(M){ serial_vec=(double*)xmalloc(M*sizeof(double)); memcpy(serial_vec,marshalled_dataset,M*sizeof(double));marshalled_dataset+=(M*sizeof(double)); value=NewVec(M); idxm=(int*)xmalloc(M*sizeof(int)); for(i=0;iid,this->enum_type,this->value,this->step,this->time); } /*}}}*/ /*PetscVecExternalResult management: */ /*FUNCTION PetscVecExternalResult::WriteData{{{1*/ void PetscVecExternalResult::WriteData(FILE* fid,bool io_gather){ int length; int type; int size; char *name = NULL; double *serialvec = NULL; extern int my_rank; /*serialize: */ VecGetSize(this->value,&size); VecToMPISerial(&serialvec,this->value); /*now, exit if we are not on cpu 0: */ if(my_rank)return; /*First write enum: */ EnumToStringx(&name,this->enum_type); length=(strlen(name)+1)*sizeof(char); fwrite(&length,sizeof(int),1,fid); fwrite(name,length,1,fid); xfree((void**)&name); /*Now write time and step: */ fwrite(&time,sizeof(double),1,fid); fwrite(&step,sizeof(int),1,fid); /*writing a double, type is 1, size is 1: */ type=1; fwrite(&type,sizeof(int),1,fid); fwrite(&size,sizeof(int),1,fid); fwrite(serialvec,size*sizeof(double),1,fid); /*Free ressources:*/ xfree((void**)&serialvec); } /*}}}1*/ /*FUNCTION PetscVecExternalResult::GetResultName{{{1*/ void PetscVecExternalResult::GetResultName(char**pname){ EnumToStringx(pname,this->enum_type); } /*}}}*/ /*FUNCTION PetscVecExternalResult::GetStep{{{1*/ int PetscVecExternalResult::GetStep(void){ return this->step; } /*}}}*/