void sens(void f(double t, double z[], double param[], double zp[]),
    void fjac(double t, double z[], double param[], double** jac),
    int ijac, double param[], int neq, int np, double t, double y[],
    double sp[] )
{
  int i,j,k,nx;
  double **jac, sum;
  // allocate memory for Jacobian
  nx = neq/(1+np);
  jac = allocDoubleMatrix(nx, nx+np,false);
  //
  if (ijac == 1)
    fjac( t,y,param,jac );
  else
    findiff1(f,param,nx,np,t,y,jac);
  // righthandside of sensitivity equation
  for (i=0;i<np;i++) {
    for (k=0;k<nx;k++) {
      sum = 0.0;
      for (j=0;j<nx;j++)
	sum = sum + jac[k][j]*y[i*nx+j];
      sum = sum + jac[k][nx+i];
      sp[i*nx+k] = sum;
    }
  }
  // deallocate memory
  freeDoubleMatrix(jac,nx);
}
Ejemplo n.º 2
0
void free3Ddouble(double*** array, int dim1, int dim2)
{
	for (int i=0; i < dim1; i++)
	{
		freeDoubleMatrix(array[i], dim2);
	}
	free(array);
}
Ejemplo n.º 3
0
/* evaluoi IF-mallin (kts. evaluateObj.m) */
double evaluateObj(doubleMatrix trainingData,doubleMatrix A, doubleMatrix means, 
	doubleMatrix variances, doubleMatrix weights, double noiseLevel) {
		
	int i, j, k;
	int *q;
	double pq;
	
	doubleMatrix f = createDoubleMatrix(1,numberOfDataRows);
	for (i = 0;i < numberOfDataRows;i++)
		IND(f,0,i) = 0;
	
	double obj = 0;
	
	for (i = 0;i < lambda.numberOfRows;i++)
		for (j = 0;j < lambda.numberOfColumns;j++) {
			if (i == j)
				IND(lambda,i,j) = noiseLevel;
			else
				IND(lambda,i,j) = 0;	
		}
		
	for (i = 0;i < diagvq.numberOfRows;i++)
		for (j = 0;j < diagvq.numberOfColumns;j++) {
			IND(diagvq,i,j) = 0;
	}
	
	for (i = 0;i < numberOfStates;i++) {
		double a;
		
		q = getState(i);
		
		pq = 1; 
		for (j = 0;j < dimensions;j++) {
			pq *= IND(weights,q[j],j);
			IND(mq,j,0) = IND(means,q[j],j);
			IND(vq,j,0) = IND(variances,q[j],j);
		}
		
		multiply(A, mq, meanq);
		

		for (j = 0;j < dimensions;j++)
			IND(diagvq,j,j) = IND(vq,j,0);
			
		multiply(A, diagvq, Adiagvq);
		multiplyABt(Adiagvq, A, AdiagvqAt);
		
		add(AdiagvqAt, lambda, sigmaq);
		
		double *indXm = Xm.element;
		double *indmq = meanq.element;
		double *indTD = trainingData.element;
		
		for (j = 0;j < Xm.numberOfColumns;j++) {
			for (k = 0;k < Xm.numberOfRows;k++)
				*(indXm++) = *(indTD++) - *(indmq++);
			indmq = meanq.element;
			}
		
		
		multiplyConst(sigmaq,2*M_PI, csigmaq);
		a = 1.0 / sqrt(fabs(determinant(csigmaq)));
		
		inverse(sigmaq, invsigmaq);
		multiply(invsigmaq, Xm, invsigmaqXm);
		
		indXm = Xm.element;
		double *indinv = invsigmaqXm.element;
		for (k = 0;k < numberOfDataRows;k++) {
			double sum = 0;
			for (j = 0;j < numberOfObserved;j++)
				sum += (*(indXm++))*(*(indinv++));
			IND(f,0,k) += pq *(a *exp(-0.5*sum));
		}
		free(q);
	}
		
	
	for (i = 0;i < numberOfDataRows;i++) {
		if (IND(f,0,i) < 0) {
			freeDoubleMatrix(f);
			return FLT_MAX;
			}
		else
			obj += log(IND(f,0,i));
	}
	
	freeDoubleMatrix(f);
	return (-obj / numberOfDataRows);
}
Ejemplo n.º 4
0
/* vapauttaa globaaleiden matriisien varaaman muistin */
void matrixFinalize() {
	int i;
	
	/* pstategivenx */
	freeDoubleMatrix(lambda);
	freeDoubleMatrix(mq);
	freeDoubleMatrix(vq);
	freeDoubleMatrix(diagvq);
	freeDoubleMatrix(Atranspose);
	freeDoubleMatrix(meanq); 
	freeDoubleMatrix(sigmaq);
	freeDoubleMatrix(csigmaq);
	freeDoubleMatrix(Adiagvq);
	freeDoubleMatrix(AdiagvqAt);
	freeDoubleMatrix(Xm);
	freeDoubleMatrix(invsigmaq);
	freeDoubleMatrix(invsigmaqXm);
	
	/* meansgivenqx & meanssgivenqx */
	freeDoubleMatrix(iLambda);
	freeDoubleMatrix(vqInv);
	freeDoubleMatrix(AtiLambda);
	freeDoubleMatrix(AtiLambdaA);
	freeDoubleMatrix(sigmaq2);
	freeDoubleMatrix(invsigmaq2);
	freeDoubleMatrix(AtiLambdaX);
	freeDoubleMatrix(vqinvMq);
	freeDoubleMatrix(repmatVqinvMq);
	freeDoubleMatrix(s2);
	
	/* muu */
	freeDoubleMatrix(p);
	
	for (i = 0;i < numberOfDataRows;i++) 
		freeDoubleMatrix(pm[i]);
	free(pm);
	
	freeDoubleMatrix(s);	 
	freeDoubleMatrix(ss);
	
	for (i = 0;i < numberOfDataRows;i++) {
		freeDoubleMatrix(ssArray[i]);
	}
	free(ssArray);
	
	for (i = 0;i < numberOfDataRows;i++) {
		freeDoubleMatrix(r[i]);
		freeDoubleMatrix(r2[i]);
	}
	free(r);
	free(r2);
	
	/* pääfunktio */
	freeDoubleMatrix(XmgsxTran);
	freeDoubleMatrix(mgsxTran);
	freeDoubleMatrix(XmgsxTranDiv);
	freeDoubleMatrix(meanMgssx);
	freeDoubleMatrix(meanMgssx2);
	freeDoubleMatrix(invMeanMgssx);
	
	freeDoubleMatrix(mmpgx);
	freeDoubleMatrix(mgsx);
	freeDoubleMatrix(mgssx);
	freeDoubleMatrix(ax);
	freeDoubleMatrix(ax2);
	

	freeDoubleMatrix(BdetInv);
	freeDoubleMatrix(Binv2);
}
Ejemplo n.º 5
0
/* pääfunktio ****************************/
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[]) {
	
	doubleMatrix trainingData, A, means, variances, weights; 
	double noiseLevel;
	
	int numberOfIterations, updateDistributions;
	int n, k, i, j, l;
	
	
	
	
	/* parametrit */
	trainingData = createDoubleMatrixMx(TRAININGDATA_IN);
	A = createDoubleMatrixMx(A_IN);
	means = createDoubleMatrixMx(MEANS_IN);
	variances = createDoubleMatrixMx(VARIANCES_IN);
	weights = createDoubleMatrixMx(WEIGHTS_IN);
	noiseLevel = mxGetScalar(NOISELEVEL_IN);
	numberOfIterations = (int)mxGetScalar(MAX_ITERATIONS_IN);
	updateDistributions = (int)mxGetScalar(UPDATE_DISTRIBUTIONS);
	
	
	/* globaaleiden muuttujien alustus */
	numberOfGaussians = mxGetM(MEANS_IN);
	dimensions = mxGetN(MEANS_IN);
	numberOfObserved = mxGetM(TRAININGDATA_IN);
	numberOfDataRows = mxGetN(TRAININGDATA_IN);
	numberOfLatent = dimensions - numberOfObserved;	
	states = statelist();
	numberOfStates = pow(numberOfGaussians,dimensions);
	
	
	/* skaalaus */
	doubleMatrix dummyA = createDoubleMatrix(numberOfObserved,dimensions);
	rescaleModel(dummyA,means,variances,weights);
	freeDoubleMatrix(dummyA);
	
	/* virhefunktion arvot */
	doubleMatrix objMatrix = createDoubleMatrix(2,numberOfIterations / RANGE);
	l = 0;
	
	n = dimensions*dimensions;
	
	/* alustetaan globaalit matriisit */
	matrixInitialize();
	
	/* EM-algoritmin pääsilmukka */
	for (k = 0;k < numberOfIterations;k++) {
		/* painojen päivitys */
		if (updateDistributions)
			meanMarginalpstategivenx(weights, trainingData, A, means, variances, weights, noiseLevel);
		
		/* A:n päivitys */
		meanssgivenx(mgssx, mgsx, trainingData, A, means, variances, weights, noiseLevel);
		
		multiplyABt(trainingData, mgsx, XmgsxTran);
		multiplyConst(XmgsxTran,1.0 / numberOfDataRows, XmgsxTranDiv);
		
		
		
		for (i = 0;i < n;i++)
			IND(meanMgssx,i,0) = 0;
		for (i = 0;i < n;i++)
			for (j = 0;j < numberOfDataRows;j++)
				IND(meanMgssx,i,0) += IND(mgssx,i,j) / numberOfDataRows;
		
		for (i = 0;i < dimensions;i++)
			for (j = 0;j < dimensions;j++)
				IND(meanMgssx2,j,i) = IND(meanMgssx,i*dimensions+j,0);
	
		inverse(meanMgssx2, invMeanMgssx);
		
		
		
		multiply(XmgsxTranDiv, invMeanMgssx, A);
		
		
		/* varianssien ja keskiarvojen päivitys */
		if (updateDistributions) {
			meanMarginalpstategivenx(mmpgx, trainingData, A, means, variances, weights, noiseLevel);
			a11meanx2(ax2, ax, trainingData, A, means, variances, weights, noiseLevel);
			
			for (i = 0;i < numberOfGaussians;i++)
				for (j = 0;j < dimensions;j++)
					IND(means,i,j) = IND(ax,i,j) / IND(mmpgx,i,j);
			
			
			for (i = 0;i < numberOfGaussians;i++)
				for (j = 0;j < dimensions;j++) 
					IND(variances,i,j) = IND(ax2,i,j) / IND(mmpgx,i,j)
						- pow(IND(means,i,j),2);
		}
		
		/* skaalataan IF-malli */
		rescaleModel(A,means,variances,weights);
		
		
		if (k % RANGE == 0) {
			/* tarkistetaan A:n validisuus (ei sisällä pelkästään nollia) */
			/* if (!isValid(variances)) { */
			if (IND(A,0,0) - NAN < EPSILON) { 
				/* jos ei enää validi, niin laitetaan tästä eteenpäin virhefunktiolle 
				vain Inf -arvoa */
				while (l < numberOfIterations / RANGE) {
					IND(objMatrix,0,l) = FLT_MAX;
					IND(objMatrix,1,l++) = k;
				}
				/* tulostetaan varianssit ja häivytään silmukasta */
				printDoubleMatrix(variances);
				break;
 
			} else {
				IND(objMatrix,0,l) = evaluateObj(trainingData, A, means, variances, weights, noiseLevel);
				IND(objMatrix,1,l++) = k;
			}
		}
	}
	
	/* vapautetaan globaaleiden matriisien varaama muisti*/
	matrixFinalize();
	
	
	
	/* ulostulot */
	A_OUT = createMxArray(A);
	MEANS_OUT = createMxArray(means);
	VARIANCES_OUT = createMxArray(variances);
	WEIGHTS_OUT = createMxArray(weights);
	OBJ_OUT = createMxArray(objMatrix);
	

	free2d(states,dimensions);
	freeDoubleMatrix(trainingData);
	freeDoubleMatrix(A);
	freeDoubleMatrix(means);
	freeDoubleMatrix(variances);
	freeDoubleMatrix(weights);
	freeDoubleMatrix(objMatrix);
	
	return;
}
Ejemplo n.º 6
0
int main(int argc, char *argv[])
{
    FILE *fp,*fX,*fY,*fV, *fXI,*fYI;
    char cBuffer[32];
    unsigned int i, j, NX, NY, nxi, nyi, size, sumx, sumy, sumz;
    double dx, dy, dxi, dyi, XI, YI, VR, VI, Xmax, Xmin, Ymax, Ymin;
    double *X, *Y, **V;

    /* MAKE SURE INPUT IS CORRECT */
    if(argc == 2 && strcmp(argv[1],"-h") == 0){
        printf("\n\nSYNTAX\npotPost nx ny nxi nyi\n\n");
        printf("DESCRIPTION\n");
        printf("Takes the file 'potential.dat' and the number of points where");
        printf(" the field is\ncalculated and produces the output X.dat, ");
        printf("Y.dat and V.dat to be used with\nmatlab. The file V.dat ");
        printf("contains Re[V]. It also writes the interpolation\nvectors XI ");
        printf("and YI that contain a number nInterp of points between the\n");
        printf("minimum and the maximum values of X and Y.\nThe parser will e");
        printf("liminate the column with repeated values from the output.\n\n");
        exit(0);
    }
    else if(argc != 5){
        printf("\n\nError: Incorrect syntax.\n\nTry: potPost nx ny nxi nyi\n");
        errorHandler("or type 'potPost -h' for help.\n");
    }
    else{
        NX = atoi(argv[1]);
        NY = atoi(argv[2]);
        nxi = atoi(argv[3]);
        nyi = atoi(argv[4]);
    }
    
    /* ALLOCATE SPACE FOR E DATA */
    size = NX*NY;
    V = doubleMatrix(size,5,0);


    /* OPEN INPUT DATA FILE, CLEAR FIRST LINE AND READ */
    if((fp = fopen("potential.dat","r")) == NULL)
        errorHandler("Error: Unable to open input file 'potential.dat'");
    for(i =0; i < 5; i++) fscanf(fp,"%s",&cBuffer);
    for(i = 0; i < size; i++){
        fscanf(fp,"%le %le %le ",&V[i][0],&V[i][1],&V[i][2]);
        fscanf(fp,"%le %le",&V[i][3],&V[i][4]);
    }
    
    /* FIND OUT CONSTANT COLUMN */
    sumx = sumy = sumz = 1;
    for(i = 1; i < size; i++){
        if(V[i][0] == V[i-1][0]) sumx++;
        if(V[i][1] == V[i-1][1]) sumy++;
        if(V[i][2] == V[i-1][2]) sumz++;
    }
    
    /* OPEN OUTPUT FILES */
    if((fX = fopen("X.dat","w")) == NULL)
        errorHandler("Error: Unable to open output file 'X.dat'");
    if((fY = fopen("Y.dat","w")) == NULL)
        errorHandler("Error: Unable to open output file 'Y.dat'");
    if((fXI = fopen("XI.dat","w")) == NULL)
        errorHandler("Error: Unable to open output file 'XI.dat'");
    if((fYI = fopen("YI.dat","w")) == NULL)
        errorHandler("Error: Unable to open output file 'YI.dat'");
    if((fV = fopen("V.dat","w")) == NULL)
        errorHandler("Error: Unable to open output file 'V.dat'");

    /* CHOOSE Xmax/Xmin AND Ymax/Ymin */
    if(sumx == size){
        Xmax = V[0][1]; Xmin = V[0][1];
        Ymax = V[0][2]; Ymin = V[0][2];
        for(i = 0; i < size; i++){
            if(V[i][1] > Xmax) Xmax = V[i][1];
            else if(V[i][1] < Xmin) Xmin = V[i][1];
            if(V[i][2] > Ymax) Ymax = V[i][2];
            else if(V[i][2] < Ymin) Ymin = V[i][2];
        }
    }
    else if(sumy == size){
        Xmax = V[0][0]; Xmin = V[0][0];
        Ymax = V[0][2]; Ymin = V[0][2];
        for(i = 0; i < size; i++){
            if(V[i][0] > Xmax) Xmax = V[i][0];
            else if(V[i][0] < Xmin) Xmin = V[i][0];
            if(V[i][2] > Ymax) Ymax = V[i][2];
            else if(V[i][2] < Ymin) Ymin = V[i][2];
        }
    }
    else if(sumz == size){
        Xmax = V[0][0]; Xmin = V[0][0];
        Ymax = V[0][1]; Ymin = V[0][1];
        for(i = 0; i < size; i++){
            if(V[i][0] > Xmax) Xmax = V[i][0];
            else if(V[i][0] < Xmin) Xmin = V[i][0];
            if(V[i][1] > Ymax) Ymax = V[i][1];
            else if(V[i][1] < Ymin) Ymin = V[i][1];
        }
    }
    else errorHandler("Error: No constant plane in input file!!");
    
dx = (Xmax - Xmin)/(NX - 1);
dy = (Ymax - Ymin)/(NY - 1);
for(i = 0; i < NX; i++) fprintf(fX,"%le\n",Xmin+i*dx);
for(i = 0; i < NY; i++) fprintf(fY,"%le\n",Ymin+i*dy);

dxi = (Xmax-Xmin)/(nxi - 1);
dyi = (Ymax-Ymin)/(nyi - 1);
for(i = 0; i < nxi; i++) fprintf(fXI,"%le\n",Xmin+i*dxi);
for(i = 0; i < nyi; i++) fprintf(fYI,"%le\n",Ymin+i*dyi);   

for(i = 0; i < NX; i++){
    for(j = 0; j < NY; j++){
        fprintf(fV,"%le ",V[i*NY + j][3]);
    }
    fprintf(fV,"\n");
}

/* CLOSE ALL FILES AND FREE MEMORY */
fclose(fp);
fclose(fX);
fclose(fXI);
fclose(fY);
fclose(fYI);
fclose(fV);
freeDoubleMatrix(V,size);

return 0;
}
Ejemplo n.º 7
0
int main(int argc, char *argv[])
{
FILE *fp,*fX,*fY,*fE,*fXI,*fYI;
char cBuffer[32];
unsigned int i, j, NX, NY, nxi, nyi, size, sumx, sumy, sumz;
double buffer, dx, dy, dxi, dyi, XI, YI, E2, Ex, Ey, Ez, ExIm, EyIm, EzIm;
double Xmax, Xmin, Ymax, Ymin;
double *X, *Y, **E;

/* MAKE SURE INPUT IS CORRECT */
if(argc == 2 && strcmp(argv[1],"-h") == 0){
    printf("\n\nSYNTAX\nfieldPost nx ny nxi nyi\n\n");
    printf("DESCRIPTION\n");
    printf("Takes the file 'field.dat' and the number of points where the ");
    printf("field is\ncalculated and produces the output X.dat, Y.dat and ");
    printf("E.dat to be used with\nmatlab. The file E.dat contains |E|. It ");
    printf("also writes the interpolation vectors XI and YI that contain a ");
    printf("number nInterp of points between the\nminimum and the maximum ");
    printf("values of X and Y.\nThe parser will eliminate the column with ");
    printf("repeated values from the output.\n\n");
    exit(0);
}
else if(argc != 5){
    printf("\n\nError: Incorrect syntax\n\nTry: fieldPost nx ny nxi nyi\n");
    errorHandler("or type 'fieldPost -h' for help.\n");
}
else{
    NX = atoi(argv[1]);
    NY = atoi(argv[2]);
    nxi = atoi(argv[3]);
    nyi = atoi(argv[4]);
}

/* ALLOCATE SPACE FOR E DATA */
size = NX*NY;
E = doubleMatrix(size,9,0);

/* OPEN INPUT DATA FILE, CLEAR FIRST LINE AND READ */
if((fp = fopen("field.dat","r")) == NULL)
    errorHandler("Error: Unable to open input file 'field.dat'.");
for(i =0; i < 9; i++) fscanf(fp,"%s",&cBuffer);
for(i = 0; i < size; i++){
    fscanf(fp,"%le %le %le %le ",&E[i][0],&E[i][1],&E[i][2],&E[i][3]);
    fscanf(fp,"%le %le %le %le %le",&E[i][4],&E[i][5],&E[i][6],&E[i][7],&E[i][8]);
}

/* FIND OUT CONSTANT COLUMN */
sumx = sumy = sumz = 1;
for(i = 1; i < size; i++){
    if(E[i][0] == E[i-1][0]) sumx++;
    if(E[i][1] == E[i-1][1]) sumy++;
    if(E[i][2] == E[i-1][2]) sumz++;
}

/* OPEN OUTPUT FILES */
if((fX = fopen("X.dat","w")) == NULL) 
    errorHandler("Error: Unable to open output file 'X.dat'");
if((fY = fopen("Y.dat","w")) == NULL)
    errorHandler("Error: Unable to open output file 'Y.dat'");
if((fXI = fopen("XI.dat","w")) == NULL)
    errorHandler("Error: Unable to open output file 'XI.dat'");
if((fYI = fopen("YI.dat","w")) == NULL)
    errorHandler("Error: Unable to open output file 'YI.dat'");
if((fE = fopen("E.dat","w")) == NULL)
    errorHandler("Error: Unable to open output file 'E.dat'");

/* CHOOSE Xmax/Xmin AND Ymax/Ymin */
if(sumx == size){
    Xmax = E[0][1]; Xmin = E[0][1];
    Ymax = E[0][2]; Ymin = E[0][2];
    for(i = 0; i < size; i++){
        if(E[i][1] > Xmax) Xmax = E[i][1];
        else if(E[i][1] < Xmin) Xmin = E[i][1];
        if(E[i][2] > Ymax) Ymax = E[i][2];
        else if(E[i][2] < Ymin) Ymin = E[i][2];
    }
}
else if(sumy == size){
    Xmax = E[0][0]; Xmin = E[0][0];
    Ymax = E[0][2]; Ymin = E[0][2];
    for(i = 0; i < size; i++){
        if(E[i][0] > Xmax) Xmax = E[i][0];
        else if(E[i][0] < Xmin) Xmin = E[i][0];
        if(E[i][2] > Ymax) Ymax = E[i][2];
        else if(E[i][2] < Ymin) Ymin = E[i][2];
    }
}
else if(sumz == size){
    Xmax = E[0][0]; Xmin = E[0][0];
    Ymax = E[0][1]; Ymin = E[0][1];
    for(i = 0; i < size; i++){
        if(E[i][0] > Xmax) Xmax = E[i][0];
        else if(E[i][0] < Xmin) Xmin = E[i][0];
        if(E[i][1] > Ymax) Ymax = E[i][1];
        else if(E[i][1] < Ymin) Ymin = E[i][1];
    }
}
else errorHandler("Error: No constant plane in input file.");

dx = (Xmax - Xmin)/(NX - 1);
dy = (Ymax - Ymin)/(NY - 1);
for(i = 0; i < NX; i++) fprintf(fX,"%le\n",Xmin+i*dx);
for(i = 0; i < NY; i++) fprintf(fY,"%le\n",Ymin+i*dy);

dxi = (Xmax-Xmin)/(nxi - 1);
dyi = (Ymax-Ymin)/(nyi - 1);
for(i = 0; i < nxi; i++) fprintf(fXI,"%le\n",Xmin+i*dxi);
for(i = 0; i < nyi; i++) fprintf(fYI,"%le\n",Ymin+i*dyi);   

for(i = 0; i < NX; i++){
    for(j = 0; j < NY; j++){
        Ex = E[i*NY + j][3];
        Ey = E[i*NY + j][5];
        Ez = E[i*NY + j][7];
        ExIm = E[i*NY + j][4];
        EyIm = E[i*NY + j][6];
        EzIm = E[i*NY + j][8];
        E2 = sqrt(Ex*Ex + Ey*Ey + Ez*Ez + ExIm*ExIm + EyIm*EyIm + EzIm*EzIm);
        fprintf(fE,"%le ",E2);
    }
    fprintf(fE,"\n");
}

/* CLOSE ALL FILES AND FREE MEMORY */
fclose(fp);
fclose(fX);
fclose(fXI);
fclose(fY);
fclose(fYI);
fclose(fE);
freeDoubleMatrix(E,size);

return 1;
}
Ejemplo n.º 8
0
/**
 * Calculates potential and electric field at the required points, and stores
 * them in file 'results.vtk' using the vtk format.
 *
 * It also calculates the force on the dielectric interface if required and
 * stores it in file 'force-mst.dat' or 'force-mp.dat' for MST and multipolar
 * approximations respectively.
 *
 * Works for quadratic interpolation in triangular elements (6-noded triangles).
 *
 * @param ANALYSIS    : [ Input ] Type of post-processing to be done
 * @param cOutputType : [ Input ] Output format type
 * @param axis        : [ Input ] Semi-axis of ellipsoidal particle
 * @param XF          : [ Input ] Points where the force should be calculated
 * @param Xinner      : [ Input ] Nodes where potential and/or field should be calculated
 * @param mNodes  : [ Input ] Coordinates of all nodes in the computational domain
 * @param mElems  : [ Input ] Connectivity of all nodes in the computational domain
 * @param vMatParam  : [ Input ] Electric properties of dielectric materials
 * @param vProbParam : [ Input ] Frequency of the applied electric field
 * @param vBCType : [ Input ] Boundary condition type for each node in the domain
 * @param vB      : [ Input ] Solution vector for the electrostatic problem
 */
int vtkPostProcess_tria6(unsigned int ANALYSIS,
                         char *cOutputType,
                         double *axis,
                         double **XF,
                         double **Xinner,
                         double **mNodes,
                         unsigned int **mElems,
                         double **vMatParam,
                         double *vProbParam,
                         unsigned int *vBCType,
                         double *vB)
{
    FILE *fp[3];
    unsigned int i, nOrder, nShape;
    double Eps, R;
    double Fcm[3], mE[6], mPot[2], Xin[3], Xcm[3], Xeval[3];
    double **Fce, **Xce;

    /* Setup the header of the output files */
    headerSetup(ANALYSIS,cOutputType,fp,Xinner);

    /* Electric potential at the required points */
    if( nInternalPoints > 0 ){
        mPot[0] = mPot[1] = 0.0;
        for(i = 0; i < 6; i++) mE[i] = 0.0;

        fprintf(fp[0],"\n");
        fprintf(fp[0],"SCALARS Re[V] double\n");
        fprintf(fp[0],"LOOKUP_TABLE default\n");
        for(i = 0; i < nInternalPoints; i++){
            Xin[0] = Xinner[i][0];
            Xin[1] = Xinner[i][1];
            Xin[2] = Xinner[i][2];

            potential_tria6(Xin,mNodes,mElems,vB,mPot);
            fprintf(fp[0],"%e\n",mPot[0]);
        }

        /* Electric potential at the required points */
        fprintf(fp[0],"\n");
        fprintf(fp[0],"SCALARS Im[V] double\n");
        fprintf(fp[0],"LOOKUP_TABLE default\n");
        for(i = 0; i < nInternalPoints; i++){
            Xin[0] = Xinner[i][0];
            Xin[1] = Xinner[i][1];
            Xin[2] = Xinner[i][2];

            potential_tria6(Xin,mNodes,mElems,vB,mPot);
            fprintf(fp[0],"%e\n",mPot[1]);
        }

        /* Electric field at the required points */
        fprintf(fp[0],"\n");
        fprintf(fp[0],"VECTORS Re[E] double\n");
        for(i = 0; i < nInternalPoints; i++){
            Xin[0] = Xinner[i][0];
            Xin[1] = Xinner[i][1];
            Xin[2] = Xinner[i][2];

            field_tria6(Xin,mNodes,mElems,vB,mE);
            fprintf(fp[0],"%e\t%e\t%e\n",mE[0],mE[2],mE[4]);
        }

        /* Electric field at the required points */
        fprintf(fp[0],"\n");
        fprintf(fp[0],"VECTORS Im[E] double\n");
        for(i = 0; i < nInternalPoints; i++){
            Xin[0] = Xinner[i][0];
            Xin[1] = Xinner[i][1];
            Xin[2] = Xinner[i][2];

            field_tria6(Xin,mNodes,mElems,vB,mE);
            fprintf(fp[0],"%e\t%e\t%e\n",mE[1],mE[3],mE[5]);
        }
        fclose(fp[0]);
    }


    /* Calculate Fdep at dielectric interfaces if required */
    if(ANALYSIS == 3 || ANALYSIS == 4){
        Fce = doubleMatrix(nElems,3,1);
        Xce = doubleMatrix(nElems,3,1);
        Eps = vMatParam[0][1]*eps0;
        forceMST_tria6(mNodes,mElems,vBCType,vB,Eps,Fce,Xce,Fcm,Xcm);
        fprintf(fp[2],"%e\t%e\t%e\t%e\t%e\t%e\n",Xcm[0],Xcm[1],Xcm[2],Fcm[0],Fcm[1],Fcm[2]);
        for(i = 0; i < nElems; i++){
            if(vBCType[mElems[i][0]-1] == 6){
                fprintf(fp[2],"%e\t%e\t%e\t",Xce[i][0],Xce[i][1],Xce[i][2]);
                fprintf(fp[2],"%e\t%e\t%e\n",Fce[i][0],Fce[i][1],Fce[i][2]);
            }
        }
        fclose(fp[2]);
        freeDoubleMatrix(Fce,nElems);
        freeDoubleMatrix(Xce,nElems);
    }

    /* Calculate Fdep at particle centre using multipolar method if required */
    else if(ANALYSIS > 4){
        multipoleSetup(ANALYSIS,axis,&nShape,&nOrder,&R);
        for(i = 0; i < nFPoints; i++){
            Xeval[0] = XF[i][0];
            Xeval[1] = XF[i][1];
            Xeval[2] = XF[i][2];
            if(nShape == 0) forceMultipole_tria6(nOrder,R,Xeval,mNodes,mElems,vB,vMatParam,vProbParam,Fcm);
            else forceEllipsoid_tria6(ANALYSIS,nOrder,axis,Xeval,mNodes,mElems,vB,vMatParam,vProbParam,Fcm);
            fprintf(fp[2],"%e\t%e\t%e\t",Xeval[0],Xeval[1],Xeval[2]);
            fprintf(fp[2],"%e\t%e\t%e\n",Fcm[0],Fcm[1],Fcm[2]);
        }
        fclose(fp[2]);
    }

    return 0;
}