/*
 * ProcessWorkspaceParameters.c:
 * for batch control solution sequence, we need more info from the model than Impx provides. We put this info here.
 */
#include "../include/cielo.h" 
#include "./Model.h"
#include "./Impx.h"

#ifdef _PARALLEL_

#undef __FUNCT__ 
#define __FUNCT__ "ProcessWorkspaceParameters"

#undef CLEANUP
#define CLEANUP ProcessWorkspaceParametersLocalCleanup(&partition);

void ProcessWorkspaceParametersLocalCleanup(double** ppartition);

int ProcessWorkspaceParameters(WorkspaceParams* this,Model* model,Vec* vec_partition){

	int noerr=1;
	int i;

	/*control: */
	char* control_type=NULL;
	char* control_type2=NULL;
	double* partition=NULL;

	if strcasecmp_eq(model->analysis_type,"control"){

		/*Initialize nstesp and tolx: */
		this->nsteps=model->nsteps;
		this->tolx=model->tolx;

		/*Serialize partition vector needed for later: */
		VecToMPISerial(&partition,vec_partition);

		/*First recover the control_types from model: */
		this->num_control_parameters=model->num_control_parameters;
		this->control_types=xmalloc(this->num_control_parameters*sizeof(char*));
		for(i=0;i<this->num_control_parameters;i++){
			control_type=model->control_types[i];
			control_type2=xmalloc((strlen(control_type)+1)*sizeof(char));
			strcpy(control_type2,control_type);
			this->control_types[i]=control_type2;
		}

		/*Initialize misfit array: */
		this->J=xmalloc(model->nsteps*sizeof(double));
		for(i=0;i<model->nsteps;i++){
			this->J[i]=0;
		}

		/*Figure out size of uset: */
		this->gsize=model->numberofgrids*6;

		/*Go through control parameters and initialize corresponding parameters, and the gradient: */
		for(i=0;i<this->num_control_parameters;i++){
			control_type=this->control_types[i];

			if strcasecmp_eq(control_type,"drag"){
				this->drag=xcalloc(this->gsize,sizeof(double));
				for(i=0;i<(int)(this->gsize/6);i++){
					this->drag[6*i+0]=model->drag[(int)(partition[i]-1)];
				}
			}
			else if strcasecmp_eq(control_type,"B"){
				this->B=xcalloc(this->gsize,sizeof(double));
				for(i=0;i<(int)(this->gsize/6);i++){
					this->B[6*i+0]=model->B[(int)(partition[i]-1)];
				}
			}
			else{
				printf("%s%s%s%s\n",__FUNCT__," error message: control parameter ",control_type," not supported yet!");
				return 0;
			}
		}

		/*Initialize observations: */
		this->u_g_obs=xcalloc(this->gsize,sizeof(double));
		for(i=0;i<(int)(this->gsize/6);i++){
			this->u_g_obs[6*i+0]=model->vx_obs[(int)(partition[i]-1)]/model->yts;
			this->u_g_obs[6*i+1]=model->vy_obs[(int)(partition[i]-1)]/model->yts;
		}

		/*Fill in fit,maxiter and optscal fields of params: */
		this->fit=xmalloc(model->nsteps*sizeof(double));
		memcpy(this->fit,model->fit,model->nsteps*sizeof(double));
		
		this->maxiter=xmalloc(model->nsteps*sizeof(double));
		memcpy(this->maxiter,model->maxiter,model->nsteps*sizeof(double));

		this->optscal=xmalloc(model->nsteps*sizeof(double));
		memcpy(this->optscal,model->optscal,model->nsteps*sizeof(double));

		/*Setup contraint bounds: */
		this->mincontrolconstraint=model->mincontrolconstraint;
		this->maxcontrolconstraint=model->maxcontrolconstraint;

	}
	else if(strcasecmp_eq(model->analysis_type,"thermalsteady") || strcasecmp_eq(model->analysis_type,"thermalsteady")){
	
		/*Initialize velocity and pressure: */
		
		/*Figure out size of uset: */
		this->gsize=model->numberofgrids*6;

		this->velocity=xcalloc(this->gsize,sizeof(double));
		this->pressure=xcalloc(this->gsize,sizeof(double));
	
		/*Serialize partition vector needed for later: */
		VecToMPISerial(&partition,vec_partition);

		for(i=0;i<(int)(this->gsize/6);i++){
			this->velocity[6*i+0]=model->vx[(int)(partition[i]-1)]/model->yts;
			this->velocity[6*i+1]=model->vy[(int)(partition[i]-1)]/model->yts;
			this->velocity[6*i+2]=model->vz[(int)(partition[i]-1)]/model->yts;
			this->pressure[6*i+0]=model->pressure[(int)(partition[i]-1)];
		}

	}
	else{
		/*Do nothing!: */
	}
	EXIT(noerr);

}

void ProcessWorkspaceParametersLocalCleanup(double** ppartition){
	xfree((void**)ppartition);
	return;
}


#endif
