Esempio n. 1
0
double PronyModel(double t, matrix* beta, void *params)
{
    matrix *Ji, *taui;
    double *p;
    double J0, J, Jval, tauval;
    int n, i;
    p = (double*) params;
    J0 = *p;

    /* Pull out all the parameter values */
    n = nRows(beta)/2;
    Ji = CreateMatrix(n, 1);
    taui = CreateMatrix(n, 1);

    for(i=0; i<n; i++) {
        setval(Ji, val(beta, 2*i, 0), i, 0);
        setval(taui, val(beta, 2*i+1, 0), i, 0);
    }

    J = J0;
    for(i=0; i<n; i++) {
        Jval = val(Ji, i, 0)*val(Ji, i, 0);
        tauval = val(taui, i, 0)*val(taui, i, 0);
        J += Jval * (1-exp(-t/tauval));
    }
    DestroyMatrix(Ji);
    DestroyMatrix(taui);
    return J;
}
Esempio n. 2
0
int main(int argc, char **argv)
{
	if (argc < 3)
		return __exception("Not found input file");

	int	 mRows1 = 0,
		mCols1 = 0,
		mRows2 = 0,
		mCols2 = 0;

	double ** matrix1 = __loadMatrix(argv[1], &mRows1, &mCols1);
	double ** matrix2 = __loadMatrix(argv[2], &mRows2, &mCols2);

	fprintf(stdout, "Matrix N1:\n");
	PrintMatrix(matrix1, mRows1, mCols1);
	fprintf(stdout, "Matrix N2:\n");
	PrintMatrix(matrix2, mRows2, mCols2);

	int zeroCount1 = GetCount(matrix1, mRows1, mCols1, true);
	int zeroCount2 = GetCount(matrix2, mRows2, mCols2, true);

	if (zeroCount1 < zeroCount2)
		fprintf(stdout, "Output matrix N1: %i\n", GetCount(matrix1, mRows1, mCols1, false));
	else
		fprintf(stdout, "Output matrix N2: %i\n", GetCount(matrix2, mRows2, mCols2, false));

	DestroyMatrix(matrix1, mRows1, mCols1);
	DestroyMatrix(matrix2, mRows2, mCols2);

	system("pause");
	return EXIT_SUCCESS;
}
Esempio n. 3
0
/* This program takes up to three arguments. The first is the Peclet number to
 * use in the calculation. The second is the number of elements to use when
 * solving the problem, and the third (optional) argument is the filename to
 * save the solution to. */
int main(int argc, char *argv[])
{
    double Pe, h;
    double left = 0;
    double right = 1;
    //double right = PI/2;
    int n;
    matrix *J, *F, *u, *Jinv, *mesh, *x;

    /* Parse arguments */
    if(argc < 2) {
        fprintf(stderr, "Too few arguments: exiting.\n");
        return 1;
    }
    Pe = atof(argv[1]);

    n = atoi(argv[2]);

    /* Create a uniform mesh */
    mesh = GenerateUniformMesh(left, right, n);

    /* Use a mesh with these node spacings */
    //mesh = ParseMatrix("[.75;.15;.0125;.0125;.0125;.0125;.0125;.0125;.0125;.0125]");

    x = MeshXCoords(mesh, left, right);

    /* All the nodes are equally spaced. */
    h = val(mesh, 0, 0);

    J = AssembleJ(&CreateElementMatrix, mesh, Pe);
    //J = AssembleJMesh(&testelem, mesh, Pe);

    F = AssembleF(&CreateElementLoad, mesh, Pe);
    //F = AssembleFMesh(&testload, mesh, Pe);

    ApplyBoundaryConditions(J, F, 0, 1);
    //ApplyBoundaryConditions(J, F, 2, 1);

    /* Invert the coefficient matrix and premultiply the load vector by it. */
    Jinv = CalcInv(J);
    u = mtxmul(Jinv, F);

    /* Print out the result */
    if(argc == 4) {
        mtxprntfile(u, argv[3]);
    } else {
        mtxprnt(x);
        puts("");
        mtxprnt(u);
    }

    /* Clean up the allocated memory */
    DestroyMatrix(J);
    DestroyMatrix(F);
    DestroyMatrix(u);
    DestroyMatrix(Jinv);
    DestroyMatrix(mesh);

    return 0;
}
Esempio n. 4
0
int main(int argc, char *argv[])
{
    int i, j, k;
    double Ti, Mj, percent;
    vector *T, *M;
    matrix *t, *Jij, *betaij, *output, *ttmp;

    /*
    if(argc < 3) {
        printf("Usage:\n"
               "fitcreep: <file> <t1> <t2> ... <tn>\n"
               "<file>: Filename containing the creep function data.\n"
               "<t1>: First retardation time\n"
               "<t2>: Second retardation time\n"
               "...\n"
               "<tn>: Nth retardation time.\n");
        exit(0);
    }
    */

    T = linspaceV(333, 363, 10);
    M = linspaceV(.05, .4, 10);

    ttmp = linspace(1e-3, 1e3, 1000);
    t = mtxtrn(ttmp);
    DestroyMatrix(ttmp);

    output = CreateMatrix(len(T)*len(M), 2+5);

    for(i=0; i<len(T); i++) {
        Ti = valV(T, i);
        for(j=0; j<len(M); j++) {
            Mj = valV(M, j);
            Jij = makedata(t, Ti, Mj);
            betaij = fitdata(t, Jij);

            setval(output, Ti, i*len(M)+j, 0);
            setval(output, Mj, i*len(M)+j, 1);
            setval(output, val(Jij, 0, 0), i*len(M)+j, 2);
            for(k=0; k<nRows(betaij); k++)
                setval(output, pow(val(betaij, k, 0), 2), i*len(T)+j, k+3);
            DestroyMatrix(Jij);
            DestroyMatrix(betaij);

            /* Print the percent done */
            percent = (1.*i*len(M)+j)/(len(M)*len(T))*100.;
            printf("%3.2f %%\r", percent);
            fflush(stdout);
        }
    }
    
    DestroyMatrix(t);
    DestroyVector(T);
    DestroyVector(M);
    mtxprntfilehdr(output, "output.csv", "T,M,J0,J1,tau1,J2,tau2\n");
    DestroyMatrix(output);
    return 0;
}
Esempio n. 5
0
/**
 * Fit the GAB parameters given water activity
 */
int main(int argc, char *argv[])
{
    matrix *data, *aw, *Xdb, *tmp0, *tmp1, *beta0, *beta;

    if(argc != 2) {
        puts("Usage:");
        puts("gab <aw.csv>");
    }
    //data = mtxloadcsv("Andrieu.csv", 0);
    data = mtxloadcsv(argv[1], 0);

    /* Get the water activity from column 1 and the moisture content from
     * column 6. */
    aw = ExtractColumn(data, 0);
    Xdb = ExtractColumn(data, 5);

    /* Stick the two matricies together and delete any rows that contain
     * empty values */
    tmp0 = AugmentMatrix(aw, Xdb);
    tmp1 = DeleteNaNRows(tmp0);
    DestroyMatrix(aw);
    DestroyMatrix(Xdb);

    /* Pull the two columns back apart */
    aw = ExtractColumn(tmp1, 0);
    Xdb = ExtractColumn(tmp1, 1);
    DestroyMatrix(tmp0);
    DestroyMatrix(tmp1);

    /* Set up the beta matrix with some initial guesses at the GAB constants.
     * The solver needs these to be pretty close to the actual values, or it
     * will fail to converge */
    beta0 = CreateOnesMatrix(3, 1);
    setval(beta0, 6, 0, 0);
    setval(beta0, .5, 1, 0);
    setval(beta0, .04, 2, 0);

    /* Attempt to fit the gab parameters to the supplied data */
    beta = fitnlm(&gab, aw, Xdb, beta0);

    /* Print out the fitted values */
    printf("C = %g\nk = %g\nXm = %g\n",
            val(beta, 0, 0),
            val(beta, 1, 0),
            val(beta, 2, 0));

    return 0;
}
Esempio n. 6
0
/* Assemble the global coefficient matrix for a non-uniform mesh. The first
 * argument is a function pointer to the function which creates the element
 * matrix, and the second is the mesh to be used.
 */
matrix* AssembleJ(matrix* (*makej)(double, double), matrix* mesh, double Pe)
{
    matrix *J, *j;
    int n, i;

    /* Determine the number of elements from the mesh */
    n = mtxlen2(mesh);

    /* Create a blank global matrix */
    J = CreateMatrix(n+1, n+1);

    for(i=0; i<n; i++) {
        /* Generate the element matrix for the specified element width */
        j = makej(Pe, val(mesh, i, 0));

        /* Add the values of the element matrix to the global matrix */
        addval(J, val(j, 0, 0), i, i);
        addval(J, val(j, 0, 1), i, i+1);
        addval(J, val(j, 1, 0), i+1, i);
        addval(J, val(j, 1, 1), i+1, i+1);

        /* Clean up */
        DestroyMatrix(j);
    }

    return J;
}
Esempio n. 7
0
int main(int argc, char **argv)
{
	if (argc < 3)
		return __exception("Not found input file");

	int	 mRows1 = 0,
		mCols1 = 0,
		mRows2 = 0,
		mCols2 = 0;

	double ** matrix1 = __loadMatrix(argv[1], &mRows1, &mCols1);
	double ** matrix2 = __loadMatrix(argv[2], &mRows2, &mCols2);

	fprintf(stdout, "Matrix N1:\n");
	PrintMatrix(matrix1, mRows1, mCols1);
	fprintf(stdout, "Matrix N2:\n");
	PrintMatrix(matrix2, mRows2, mCols2);

	int S1 = Calculate(matrix1, mRows1, mCols1);
	int S2 = Calculate(matrix2, mRows2, mCols2);

	int row, cols;
	double ** matrix;

	if(S1 < S2)
	{
		matrix = matrix1;
		row = mRows1;
		cols = mCols1;
	}
	else
	{
		matrix = matrix2;
		row = mRows2;
		cols = mCols2;
	}

	for (int i = 0; i < row; i++)
		printf("Min element %i line = %3.1f\n", i+1, CalculateRow(matrix, i, cols));

	DestroyMatrix(matrix1, mRows1, mCols1);
	DestroyMatrix(matrix2, mRows2, mCols2);

	system("pause");
	return EXIT_SUCCESS;
}
Esempio n. 8
0
/**
 * @brief Explicit time integration algorithm (Forward Euler)
 *
 * This solver fails horribly if a Neumann boundary condition is imposed. Also,
 * it may not be entirely stable anyway.
 *
 * @param problem The struct containing the problem to solve
 * @returns A matrix with the solutions at each node
 */
matrix* LinSolve1DTrans(struct fe1d *problem)
{
    matrix *du, *u;
    matrix *tmp1, *tmp2, *tmp3, *tmp4;
    matrix *dresult, *result;
    solution *prev; /* The solution at the previous time step */

    /* Initialize the matricies */
    DestroyMatrix(problem->J);
    DestroyMatrix(problem->dJ);
    DestroyMatrix(problem->F);
    AssembleJ1D(problem, NULL);
    AssembledJ1D(problem, NULL);
    AssembleF1D(problem, NULL);
    problem->applybcs(problem);


    /* Get the previous solution */
    prev = FetchSolution(problem, problem->t-1);
    du = prev->dval;
    u = prev->val;

    tmp1 = mtxmulconst(du, problem->dt);
    tmp2 = mtxadd(u, tmp1);
    mtxneg(tmp2);
    tmp3 = mtxmul(problem->J, tmp2);

    tmp4 = mtxadd(problem->F, tmp3);

    /* Solve for du/dt */
    dresult = SolveMatrixEquation(problem->dJ, tmp4);

    DestroyMatrix(tmp1);
    DestroyMatrix(tmp2);
    DestroyMatrix(tmp3);
    DestroyMatrix(tmp4);

    /* Solve for u */
    tmp1 = mtxmul(problem->dJ, dresult);
    mtxneg(tmp1);
    tmp2 = mtxadd(problem->F, tmp1);
    result = SolveMatrixEquation(problem->J, tmp2);

    DestroyMatrix(tmp1);
    DestroyMatrix(tmp2);

    StoreSolution(problem, result, dresult);

    return result;
}
Esempio n. 9
0
/**
 * Equivalent of the Matlab "regress" function. Solves for the fitting
 * parameters using matrix algebra. Each column of the X matrix is a set of data
 * to used to fit a single parameter. To fit a constant, X should contain a
 * column of ones.
 * \f[
 * \underline{b} = (\underline{\underline{X}}^T\underline{\underline{X}})^{-1}
 *     \underline{\underline{X}}^T\underline{y}
 * \f]
 * @param y Column vector of dependent variable values
 * @param X Matrix of independent variable values, one variable per column
 * @returns Column matrix of fitted parameters. Each row corresponds to a
 *      column in the supplies X matrix
 */
matrix* regress(matrix *y, matrix *X)
{
    matrix *Xt, *XtX, *XtXinv, *XtXinvXt, *beta;

    Xt = mtxtrn(X);
    XtX = mtxmul(Xt, X);
    XtXinv = CalcInv(XtX);
    XtXinvXt = mtxmul(XtXinv, Xt);

    beta = mtxmul(XtXinvXt, y);

    DestroyMatrix(Xt);
    DestroyMatrix(XtX);
    DestroyMatrix(XtXinv);
    DestroyMatrix(XtXinvXt);

    return beta;
}
Esempio n. 10
0
/**
 * Calculate equilibrium moisture content (Xe) using nonlinear regression.
 * This function is made obsolete by CalcXeIt
 * @param initial Row number of the first data point to use in the calculation
 * @param t Column matrix of time values [s]
 * @param Xdb Column matrix of moisture contents [kg/kg db]
 * @param Xe0 Initial guess for Xe. The initial value for kf is hard coded below
 * @returns Equilibrium moisture content [kg/kg db]
 *
 * @see fitnlm XeModel CalcXeIt
 */
double NCalcXe(int initial, vector *t, vector *Xdb, double Xe0)
{
    double Xe = Xe0; /* Set Xe to the initial guess */
    matrix *beta, /* Matrix of fitting values */
           *beta0,
           *Xadj,
           *tadj;
    int i; /* Loop index */

    /* Print out the starting row */
    printf("Starting calculation from row %d.\n", initial);

    /* Set the initial moisture content */
    Xinit = valV(Xdb, initial);
    beta0 = CreateMatrix(2,1);
    setval(beta0, Xe0, 0, 0);
    setval(beta0, 4e-6, 1, 0);

    /* Make smaller matricies that contain only the "good" data. */
    tadj = CreateMatrix(len(Xdb) - initial, 1);
    Xadj = CreateMatrix(len(Xdb) - initial, 1);

    for(i=initial; i<len(t); i++) {
        setval(tadj, valV(t, i), i-initial, 0);
        setval(Xadj, valV(Xdb, i), i-initial, 0);
    }

    /* Actually find Xe */
    beta = fitnlm(&XeModel, tadj, Xadj, beta0);

    Xe = val(beta, 0, 0);
    //mtxprnt(beta);
    //mtxprnt(beta0);

    DestroyMatrix(beta);
    DestroyMatrix(beta0);
    DestroyMatrix(tadj);
    DestroyMatrix(Xadj);

    return Xe;
}
Esempio n. 11
0
int main(int argc, char **argv) {
  char *input_filename = NULL, *output_filename = NULL;
  if (!parse_args(argc, argv, &input_filename, &output_filename)) {
    help(argv[0]);
    exit(-1);
  }
  FILE *fout = NULL;
  if (!(fout = fopen(output_filename,"w")))  fout = stdout;
  Matrix *m1 = NULL, *covariance;
  
  m1 = ReadMatrix(input_filename);
  covariance = Covariance(m1);
  WriteMatrix(fout, covariance);
  if (!(fout == stdout)) {
    printf("Output was written in %s\n", output_filename);
    fclose(fout);
  }

  DestroyMatrix(m1);
  DestroyMatrix(covariance);
  return 0;
}
Esempio n. 12
0
LRESULT CALLBACK ScreensaverProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	MATRIX* matrix = GetMatrix(hwndDlg);

	switch(uMsg)
	{
		case WM_NCCREATE:
			_ShowCursor(0);

			matrix = CreateMatrix(hwndDlg, ((CREATESTRUCT*)lParam)->cx, ((CREATESTRUCT*)lParam)->cy);

			if(!matrix)
			{
				MessageBox(hwndDlg, L"Ошибка работы скринсейвера", L"Ошибка", MB_OK | MB_ICONSTOP);
				return 0;
			}

			SetMatrix(hwndDlg, matrix);
			SetTimer(hwndDlg, 0xdeadbeef, ((SPEED_MAX - g_nMatrixSpeed) + SPEED_MIN) * 10, 0);

			return 1;

		case WM_TIMER:
			DecodeMatrix(hwndDlg, matrix);
			break;

		case WM_KEYDOWN:
			if(wParam == VK_ESCAPE)
				SendMessage(hwndDlg, WM_CLOSE, 0, 0);

			break;

		case WM_CLOSE:
			_ShowCursor(1);
			DestroyMatrix(matrix);

			DestroyWindow(hwndDlg);
			PostQuitMessage(0);

			break;

		default:
			return DefWindowProc(hwndDlg, uMsg, wParam, lParam);
	}

	return 0;
}
Esempio n. 13
0
matrix* AssembleF(matrix* (*makef)(double, double), matrix* mesh, double Pe)
{
    matrix *F, *f;
    int n, i;

    n = mtxlen2(mesh);

    F = CreateMatrix(n+1, 1);

    for(i=0; i<n; i++) {
        f = makef(Pe, val(mesh, i, 0));

        addval(F, val(f, 0, 0), i, 0);
        addval(F, val(f, 1, 0), i+1, 0);

        DestroyMatrix(f);
    }

    return F;
}
Esempio n. 14
0
matrix* fitdata(matrix *t, matrix *J)
{
    double J0, Jt;
    J0 = val(J, 0, 0);
    Jt = val(J, nRows(J)-1, 0);

    matrix *beta0, *beta;
    beta0 = CreateMatrix(4, 1);
    setval(beta0,
           sqrt( .5*(Jt-J0) ),
           0, 0);
    setval(beta0, sqrt(10), 1, 0);
    setval(beta0,
           sqrt( .5*(Jt-J0) ),
           2, 0);
    setval(beta0, sqrt(200), 3, 0);
    beta = fitnlmP(&PronyModel, t, J, beta0, &J0);
    DestroyMatrix(beta0);
    return beta;
}
Esempio n. 15
0
/**
 * Matlab "polyfit" function. This fits the x-y data to a polynomial of
 * arbitrary order using the regress function.
 * @param x Column vector of dependent variable values
 * @param y Column vector of independent variable values
 * @param order Degree of the polynomial to fit to
 * @returns Column matrix of fitted parameters. Element n corresponds to the
 *      coefficient in front of x^n.
 */
matrix* polyfit(matrix* x, matrix* y, int order)
{
    matrix *X, *beta;
    int i, j, nelem;

    X = NULL;
    nelem = nRows(x);

    X = CreateMatrix(nelem, order+1);

    for(i=0; i<=nelem; i++) {
        for(j=0; j<=order; j++) {
            setval(X, pow(val(x, i, 0), j), i, j);
        }
    }

    beta = regress(y, X);
    DestroyMatrix(X);

    return beta;
}
Esempio n. 16
0
/**
 * Calculate the equilibrium moisture content. This function determines the best
 * value of Xe to make a plot of \f$\ln\frac{X-X_e}{X_0-X_e}\f$ vs time linear.
 * In order to do this, it fits the data to the equation \f$y = a t + b\f$, where
 * \f$y = \ln(X-X_e)\f$ and \f$b = \ln(X_0-X_e)\f$, and then solves the equation
 * \f$F(X_e) = b - \ln(X_0-X_e) = 0\f$ using Newton's method.
 *
 * This function is made obsolete by CalcXeIt
 *
 * @param t Column matrix containing time during drying [s]
 * @param Xdb Column matrix of moisture content [kg/kg db]
 * @param Xe0 Initial guess for equilibrium moisture content.
 * @returns Equilibrium moisture content [kg/kg db]
 *
 * @see polyfit CalcXeIt
 */
double CalcXe(int initial, matrix *t, matrix *Xdb, double Xe0)
{
    double f, df, /* Function values and derivatives */
           b, /* Fitting parameters. Only the constant matters */
           tol = 1e-10, /* Tolerance for Newton's method */
           Xe = Xe0, /* Set Xe to the initial guess */
           Xep, /* Previous guess */
           X0, /* Initial moisture content */
           r2;
    matrix *beta, /* Matrix of fitting values */
           *y, /* Set equal to ln(X - Xe) */
           *Xadj,
           *tadj;
    int i, /* Loop index */
        iter = 0; /* Current iteration */

    /* Set the initial moisture content */
    X0 = val(Xdb, initial, 0);

    /* Make smaller matricies that contain only the "good" data. */
    tadj = CreateMatrix(nRows(Xdb) - initial, 1);
    Xadj = CreateMatrix(nRows(Xdb) - initial, 1);

    for(i=initial; i<nRows(t); i++) {
        setval(tadj, val(t, i, 0), i-initial, 0);
        setval(Xadj, val(Xdb, i, 0), i-initial, 0);
    }

    /* Actually find Xe */
    do {
        /* Make a y matrix containing ln(Xdb - Xe) */
        y = CreateMatrix(nRows(Xadj), 1);
        for(i=0; i<nRows(Xadj); i++)
            setval(y, log(val(Xadj, i, 0) - Xe), i, 0);

        /* Calculate b */
        beta = polyfit(tadj, y, 1);
        r2 = rsquared(tadj, y, beta);
        b = val(beta, 0, 0);

        /* Calculate f and df */
        f = b - log(X0 - Xe);
        df = 1/(X0 - Xe);

        /* Calculate the new value of Xe */
        Xep = Xe;
        Xe = Xe - f/df;

        /* Clean up */
        DestroyMatrix(y);
        DestroyMatrix(beta);

        /* Keep track of how many iterations we've gone through */
        iter++;

        /* Print out the current value */
        printf("Xe = %g, R^2 = %g\n", Xe, r2);
        if(Xe < 0) {
            printf("Failure to converge after %d iterations.\n", iter);
            return 0;
        }
    } while( fabs(Xe - Xep) > tol ); /* Check our value */

    /* Print out how many iterations it took to find Xe */
    printf("Solution converged after %d iterations.\n", iter);

    return Xe;
}
Esempio n. 17
0
/**
 * Calculate the equilibrium moisture content. This algorithm takes an initial
 * guess for Xe and then fits a linear equation to
 * \f$\ln\frac{X-X_e}{X_0-X_e}\f$ vs. \f$ t\f$. It then determines the \f$R^2\f$
 * value for that set of coefficients and then iteratively improves the fit
 * using Newton's method.
 * @param initial Row number of the first data point to use
 * @param t Vector of time values [s]
 * @param Xdb Vector of moisture contents [kg/kg db]
 * @param Xe0 Initial guess for equilibrium moisture content [kg/kg db]
 * @returns Equilibrium moisture content [kg/kg db]
 *
 * @see regress
 */
double CalcXeIt(int initial, vector *t, vector *Xdb, double Xe0)
{
    int iter = 0, /* Keep track of the number of iterations */
        i; /* Loop index */
    double Xinit, /* Initial moisture content */
           Xe, /* Current guess for Xe */
           Xep, /* Previous guess for Xe */
           dR, /* First derivative of R^2 with respect to Xe */
           d2R, /* Second derivative of R^2 */
           kF,
           tol = 1e-7, /* How close Xe and Xep need to be before we stop */
           h = 1e-7, /* Used for numerical differentiation */
           m = 2; /* Used to increase the rate of convergence */
    matrix *beta, /* Beta value from regress */
           *beta_ph, /* Same, but calculated at Xe + h */
           *beta_mh, /* Beta at Xe - h */
           *tmp_ph, /* Same as beta_ph, but with an extra zero to make rsquared
                       happy */
           *tmp,
           *tmp_mh,
           *y, /* y values */
           *yph, /* Same as y, but at Xe + h */
           *ymh, /* y at Xe - h */
           *tadj, /* New matrix of t values that starts at the initial row */
           *Xadj; /* Same as tadj, but for Xdb */

    /* Set the initial moisture content */
    Xinit = valV(Xdb, initial);
    /* Set the first value of Xe to Xe0 */
    Xe = Xe0;

    /* Make smaller matricies that contain only the "good" data. */
    tadj = CreateMatrix(len(t) - initial, 1);
    Xadj = CreateMatrix(len(Xdb) - initial, 1);
    for(i=initial; i<len(t); i++) {
        /* In addition to just copying the data, subtract the initial time from
         * each value to make sure that the intercept for the model goes through
         * the origin */
        setval(tadj, valV(t, i)-valV(t, initial), i-initial, 0);
        setval(Xadj, valV(Xdb, i), i-initial, 0);
    }

    /* Actually find Xe */
    do {
        /* Make a y matrix containing ln((Xdb - Xe)/(X0-Xe)) */
        y = CreateMatrix(nRows(Xadj), 1);
        for(i=0; i<nRows(Xadj); i++)
            setval(y, log((val(Xadj, i, 0) - Xe)/(Xinit - Xe)), i, 0);
        /* Calculate the kf parameter */
        beta = regress(y, tadj);

        /* Do the same, but at Xe - h */
        ymh = CreateMatrix(nRows(Xadj), 1);
        for(i=0; i<nRows(Xadj); i++)
            setval(ymh, log((val(Xadj, i, 0) - Xe-h)/(Xinit - Xe-h)), i, 0);
        beta_ph = regress(ymh, tadj);

        /* At Xe + h */
        yph= CreateMatrix(nRows(Xadj), 1);
        for(i=0; i<nRows(Xadj); i++)
            setval(yph, log((val(Xadj, i, 0) - Xe+h)/(Xinit - Xe+h)), i, 0);
        beta_mh = regress(yph, tadj);

        /* Add in a constant parameter of zero to the beta matrix. Do this for
         * each of the beta matricies we've got. */
        tmp_ph = CreateMatrix(2,1);
        setval(tmp_ph, 0, 0, 0);
        setval(tmp_ph, val(beta_ph, 0, 0), 1, 0);

        tmp = CreateMatrix(2,1);
        setval(tmp, 0, 0, 0);
        setval(tmp, val(beta, 0, 0), 1, 0);

        tmp_mh = CreateMatrix(2,1);
        setval(tmp_mh, 0, 0, 0);
        setval(tmp_mh, val(beta_mh, 0, 0), 1, 0);

        /* Calculate f and df */
        dR = (rsquared(tadj, yph, tmp_ph) - rsquared(tadj, ymh, tmp_mh))/(2*h);
        d2R = (rsquared(tadj, yph, tmp_ph) - 2*rsquared(tadj, y, tmp) + rsquared(tadj, ymh, tmp_mh))/(h*h);
        if(d2R == 0) {
            printf("Terminating due to division by zero.\n");
            break;
        }

        /* Calculate the new value of Xe */
        Xep = Xe;
        Xe = Xep + m*dR/d2R;

        kF = val(tmp, 1, 0);

        /* Clean up */
        DestroyMatrix(y);
        DestroyMatrix(yph);
        DestroyMatrix(ymh);
        DestroyMatrix(beta);
        DestroyMatrix(tmp_ph);
        DestroyMatrix(tmp);
        DestroyMatrix(tmp_mh);

        /* Keep track of how many iterations we've gone through */
        iter++;

        /* Print out the current value */
        printf("Xe = %g\r", Xe);

        /* If Xe ever goes negative, admit defeat. */
        if(Xe < 0) {
            printf("Failure to converge after %d iterations.\n", iter);
            return Xe;
        }
    } while( fabs(Xe - Xep) > tol ); /* Check our value */

    /* Print out how many iterations it took to find Xe */
    printf("Solution converged after %d iterations.\n", iter);
    printf("kF = %g\n", kF);

    return Xe;
}
Esempio n. 18
0
/**
 * Implicit time integration solver. (Nonlinear version)
 * Works with both backward difference
 * integration (BD) and the trapazoid rule (TR). In either case, the algorithm
 * is supposed to be unconditionally stable. This function only solves the
 * problem at the next time step. In order to solve for the desired variables
 * over the entire time domain, call this function repeatedly.
 *
 * The time deriviative is calculated using the following formula:
 * y'(t1) = a/dt * [y(t1) - y(t0)] + b*y'(t0)
 * Here, t1 is the time at the current time step and t0 is at the previous one.
 * The variables a and b are constants that determine which algorithm is used
 * to approximate the derivative. For a=1, b=0, backward difference is used,
 * and for a=2, b=-1, trapazoid rule is used.
 *
 * @param problem Finite element problem to solve
 * @param guess Initial guess at the solution for the next time step. If this
 *      is not supplied (NULL), then the solution is predicted based on the
 *      previous time steps.
 * @returns Pointer to a matrix of the calculated values. This can be safely
 *      disregarded since the matrix is also stored in the finite element
 *      problem structure.
 */
matrix* NLinSolve1DTransImp(struct fe1d *problem, matrix *guess)
{
    int iter = 0; /* Current iteration number */
    int maxiter = 5000; /* Maximum allowed iterations before terminating */

    /* Constants that determine the integration algorithm. If a=1 and b=0, then
     * the backward difference method is being used. For the trapazoid rule,
     * a=2, and b=-1. */
    int a, b;
    solution *prev; /* Solution at the previous time step */
    matrix *J, *F, *R; /* Jacobian matrix and the residuals matrix */
    matrix *tmp1, *tmp2; /* Temporary matricies */
    matrix *u, *du, *dx;
    matrix *dguess; /* Time derivative of the guess */

    /* Use BD */
    a = 1; b = 0;
    /* Note: This solver doesn't work at all with anything but backward
     * difference for time integration. The linear one doesn't either, but it
     * at least contains some code for it. */

    /* Get the previous solution */
    prev = FetchSolution(problem, problem->t-1);
    du = prev->dval;
    u = prev->val;

    /* Predict the next solution if an initial guess isn't supplied. */
    if(!guess)
        guess = PredictSolnO0(problem);

    dx = NULL;
    //exit(0);

    do {
        iter++;

        /* Quit if we've reached the maximum number of iterations */
        if(iter == maxiter)
            break;

        problem->guess = guess;

        /* Delete the matricies from the previous iteration */
        DestroyMatrix(problem->J);
        DestroyMatrix(problem->dJ);
        DestroyMatrix(problem->F);
        /* Delete the dx matrix from the previous iteration. */
        if(dx)
            DestroyMatrix(dx);
        /* Initialize the matricies */
        AssembleJ1D(problem, guess);
        AssembledJ1D(problem, guess);
        AssembleF1D(problem, guess);

        //problem->guess = NULL;

        /* Calculate the Jacobian matrix */
        tmp1 = mtxmulconst(problem->dJ, a/problem->dt);
        J = mtxadd(tmp1, problem->J);
        DestroyMatrix(tmp1);

        /* Calculate the load vector */
        tmp1 = mtxmulconst(problem->dJ, a/problem->dt);
        tmp2 = mtxmul(tmp1, u);
        F = mtxadd(problem->F, tmp2);
        DestroyMatrix(tmp1);
        DestroyMatrix(tmp2);

        /* Apply boundary conditions. */
        DestroyMatrix(problem->J);
        DestroyMatrix(problem->F);
        problem->J = J;
        problem->F = F;
        problem->applybcs(problem);

        /* Calculate the residual vector */
        tmp1 = mtxmul(problem->J, guess);
        mtxneg(tmp1);
        R = mtxadd(problem->F, tmp1);
        DestroyMatrix(tmp1);

        //mtxprnt(problem->J);
        //puts("");
        //mtxprnt(problem->dJ);
        //puts("");
        //mtxprnt(problem->F);

        /* Solve for dx */
        dx = SolveMatrixEquation(J, R);

        /* Delete the residual matrix and the Jacobian matrix*/
        DestroyMatrix(R);

        /* Add the change in the unknowns to the guess from the previous
         * iteration */
        tmp1 = mtxadd(guess, dx);
        DestroyMatrix(guess);
        guess = tmp1;

#ifdef VERBOSE_OUTPUT
        /* Print the current iteration number to the console. */
        printf("\rIteration %d", iter);
        fflush(stdout); // Flush the output buffer.
#endif
    } while(!CheckConverg1D(problem, dx));
    /* Delete the final dx matrix */
    DestroyMatrix(dx);

    if(iter==maxiter) {
        printf("Nonlinear solver failed to converge. "
               "Maximum number of iterations reached.\n"
               "Failed to calculate solution at time step %d of %d\n"
               "Exiting.\n",
                problem->t, problem->maxsteps);
        printf("Current step size: %g\n", problem->dt);
        PrintSolution(problem, problem->t-1);
        printf("Current guess:\n");
        PrintGuess(problem, guess);
        exit(0);
    }

#ifdef VERBOSE_OUTPUT
    if(iter == -1)
        /* If we've determined the matrix to be singular by calculating the
         * determinant, then output the appropriate error message. */
        printf("\rSingular matrix.\n");
    else if(iter == maxiter)
        /* If the solver didn't find a solution in the specified number of
         * iterations, then say so. */
        printf("\rNonlinear solver failed to converge. "
               "Maximum number of iterations reached.\n");
    else
        /* Print out the number of iterations it took to converge
         * successfully. */
        printf("\rNonlinear solver converged after %d iterations.\n", iter);
#endif

    /* Solve for the time derivative of the result. */
    dguess = CalcTimeDerivative(problem, guess);

    StoreSolution(problem, guess, dguess);
    /* Delete the time derivative of the pervious solution to save memory. */
    //DeleteTimeDeriv(prev);

    return guess;
}
Esempio n. 19
0
/**
 * Nonlinear finite element solver. (1D version)
 *
 * This does all the same stuff as the linear
 * solver (assembling the global matricies), but utilizes an initial guess to
 * calculate them. It then iterates using Newton's method and updates this
 * guess at each iteration.
 *
 * @param problem The struct containing the problem to solve
 * @param guess The initial guess
 *
 * @returns A matrix with the solution at each node
 */
matrix* NLinSolve1D(struct fe1d *problem, matrix *guess)
{
    matrix *dx; /* How much to update the guess by */
    matrix *newguess;
    //int rows = (2*problem->mesh->nelemx+1)*(2*problem->mesh->nelemy+1);
    int rows = problem->nrows;
    int iter = 0;
    int maxiter = 500;

    if(!guess) {
        guess = CreateMatrix(rows*problem->nvars, 1);
    }

    do {
        iter++;

        if(problem->J)
            DestroyMatrix(problem->J);
        if(problem->F)
            DestroyMatrix(problem->F);

        AssembleJ1D(problem, guess);
        problem->F = CreateMatrix(rows*problem->nvars, 1);
        //AssembleF(problem, guess);
        problem->applybcs(problem);

        //if(!CalcDeterminant(problem->J)) {
        //    iter = -1;
        //   break;
        //}

        /* ToDo: Write this function! */
        CalcResidual1D(problem, guess);
        dx = SolveMatrixEquation(problem->J, problem->R);
        newguess = mtxadd(guess, dx);
        DestroyMatrix(guess);
        guess = newguess;

        /* Quit if we've reached the maximum number of iterations */
        if(iter == maxiter)
            break;

        /* Print the current iteration number to the console. */
        printf("\rIteration %d", iter);
        fflush(stdout); // Flush the output buffer.

    } while(!CheckConverg1D(problem, dx));
    /* ^^ Also quit if the dx variable is small enough. */

    if(iter == -1)
        /* If we've determined the matrix to be singular by calculating the
         * determinant, then output the appropriate error message. */
        printf("\rSingular matrix.\n");
    else if(iter == maxiter)
        /* If the solver didn't find a solution in the specified number of
         * iterations, then say so. */
        printf("\rNonlinear solver failed to converge. "
               "Maximum number of iterations reached.\n");
    else
        /* Print out the number of iterations it took to converge
         * successfully. */
        printf("\rNonlinear solver converged after %d iterations.\n", iter);

    return guess;
}
Esempio n. 20
0
/**
 * Implicit time integration solver. (Linear version)
 *
 * Works with both backward difference
 * integration (BD) and the trapazoid rule (TR). In either case, the algorithm
 * is supposed to be unconditionally stable. This function only solves the
 * problem at the next time step. In order to solve for the desired variables
 * over the entire time domain, call this function repeatedly.
 *
 * The time deriviative is calculated using the following formula:
 * y'(t1) = a/dt * [y(t1) - y(t0)] + b*y'(t0)
 * Here, t1 is the time at the current time step and t0 is at the previous one.
 * The variables a and b are constants that determine which algorithm is used
 * to approximate the derivative. For a=1, b=0, backward difference is used,
 * and for a=2, b=-1, trapazoid rule is used.
 *
 * @param problem The problem to solve
 * @returns A matrix with the solutions at each node
 */
matrix* LinSolve1DTransImp(struct fe1d *problem)
{
    /* Constants that determine the integration algorithm. If a=1 and b=0, then
     * the backward difference method is being used. For the trapazoid rule,
     * a=2, and b=-1. */
    int a, b;
    matrix *u, /* Used to store the solution at the previous time step */
           *du; /* Derivative of u at the previous time step */
    /* Used to store intermediate calculations */
    matrix *tmp1, *tmp2, *tmp3, *tmp4;
    matrix *dresult, *result;
    solution *prev; /* Solution at previous time step */

    /* Use BD for testing */
    a = 1; b = 0;

    /* Initialize the matricies */
    DestroyMatrix(problem->J);
    DestroyMatrix(problem->dJ);
    DestroyMatrix(problem->F);
    AssembleJ1D(problem, NULL);
    AssembledJ1D(problem, NULL);
    AssembleF1D(problem, NULL);

    /* Get the previous solution */
    prev = FetchSolution(problem, problem->t-1);
    du = prev->dval;
    u = prev->val;

    /* Calculate the matrix to be multiplied by the unknown vector */
    tmp1 = mtxmulconst(problem->dJ, a/problem->dt);
    tmp2 = mtxadd(tmp1, problem->J);

    DestroyMatrix(tmp1);

    /* Determine the right hand side of the equation. The if statement is there
     * so that this function can be used for both TR and BD, but not waste an
     * extra step multiplying by 0 for BD. */
    tmp1 = mtxmulconst(problem->dJ, a/problem->dt);
    tmp3 = mtxmul(tmp1, u);

    DestroyMatrix(tmp1);

    if(b) {
        tmp1 = mtxmulconst(problem->dJ, b);
        tmp4 = mtxmul(tmp1, du);
        mtxneg(tmp4);
        DestroyMatrix(tmp1);

        tmp1 = mtxadd(tmp3, tmp4);
        DestroyMatrix(tmp4);
        DestroyMatrix(tmp3);
    } else {
        tmp1 = tmp3;
    }

    tmp3 = mtxadd(tmp1, problem->F);
    DestroyMatrix(tmp1);

    /* Apply boundary conditions here so that any Dirchlet boundary conditions
     * are imposed properly for the transient solver. Doing it here, rather than
     * above guarantees that the specified value on the boundaries doesn't
     * change randomly. */
    DestroyMatrix(problem->J);
    DestroyMatrix(problem->F);
    problem->J = tmp2;
    problem->F = tmp3;
    problem->applybcs(problem);

    /* Solve the matrix equation to find the nodal values */
    result = SolveMatrixEquation(problem->J, problem->F);

    /* Solve for the time derivative of the result. */
    dresult = CalcTimeDerivative(problem, result);

    StoreSolution(problem, result, dresult);
    /* Delete the time derivative of the pervious solution to save memory. */
    DeleteTimeDeriv(prev);

    return result;
}
Esempio n. 21
0
void LoadBalance3d(Mesh *mesh){

  int n,p,k,v,f;

  int nprocs = mesh->nprocs;
  int procid = mesh->procid;
  int **EToV = mesh->EToV;
  double **VX = mesh->GX;
  double **VY = mesh->GY;
  double **VZ = mesh->GZ;

  if(!procid) printf("Root: Entering LoadBalance\n");

  int Nverts = mesh->Nverts;
  
  int *Kprocs = BuildIntVector(nprocs);

  /* local number of elements */
  int Klocal = mesh->K;

  /* find number of elements on all processors */
  MPI_Allgather(&Klocal, 1, MPI_INT, Kprocs, 1, MPI_INT, MPI_COMM_WORLD);

  /* element distribution -- cumulative element count on processes */
  idxtype *elmdist = idxmalloc(nprocs+1, "elmdist");

  elmdist[0] = 0;
  for(p=0;p<nprocs;++p)
    elmdist[p+1] = elmdist[p] + Kprocs[p];

  /* list of element starts */
  idxtype *eptr = idxmalloc(Klocal+1, "eptr");

  eptr[0] = 0;
  for(k=0;k<Klocal;++k)
    eptr[k+1] = eptr[k] + Nverts;

  /* local element to vertex */
  idxtype *eind = idxmalloc(Nverts*Klocal, "eind");

  for(k=0;k<Klocal;++k)
    for(n=0;n<Nverts;++n)
      eind[k*Nverts+n] = EToV[k][n];

  /* weight per element */
  idxtype *elmwgt = idxmalloc(Klocal, "elmwgt");

  for(k=0;k<Klocal;++k)
    elmwgt[k] = 1.;
  
  /* weight flag */
  int wgtflag = 0;
  
  /* number flag (1=fortran, 0=c) */
  int numflag = 0;

  /* ncon = 1 */
  int ncon = 1;

  /* nodes on element face */
  int ncommonnodes = 3;
  
  /* number of partitions */
  int nparts = nprocs;

  /* tpwgts */
  float *tpwgts = (float*) calloc(Klocal, sizeof(float));
 
  for(k=0;k<Klocal;++k)
    tpwgts[k] = 1./(float)nprocs;

  float ubvec[MAXNCON];

  for (n=0; n<ncon; ++n)
    ubvec[n] = UNBALANCE_FRACTION;
  
  int options[10];
  
  options[0] = 1;
  options[PMV3_OPTION_DBGLVL] = 7;
  options[PMV3_OPTION_SEED] = 0;

  int edgecut;

  idxtype *part = idxmalloc(Klocal, "part");

  MPI_Comm comm;
  MPI_Comm_dup(MPI_COMM_WORLD, &comm);

  ParMETIS_V3_PartMeshKway
    (elmdist, 
     eptr, 
     eind, 
     elmwgt, 
     &wgtflag, 
     &numflag, 
     &ncon, 
     &ncommonnodes,
     &nparts, 
     tpwgts, 
     ubvec, 
     options, 
     &edgecut,
     part, 
     &comm);

  int **outlist = (int**) calloc(nprocs, sizeof(int*));
  double **xoutlist = (double**) calloc(nprocs, sizeof(double*));
  double **youtlist = (double**) calloc(nprocs, sizeof(double*));
  double **zoutlist = (double**) calloc(nprocs, sizeof(double*));

  int *outK = (int*) calloc(nprocs, sizeof(int));
  
  int *inK = (int*) calloc(nprocs, sizeof(int));

  MPI_Request *inrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request));
  MPI_Request *outrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request));
  MPI_Request *xinrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request));
  MPI_Request *xoutrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request));
  MPI_Request *yinrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request));
  MPI_Request *youtrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request));
  MPI_Request *zinrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request));
  MPI_Request *zoutrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request));

  for(k=0;k<Klocal;++k)
    ++outK[part[k]];
  
  /* get count of incoming elements from each process */
  MPI_Alltoall(outK, 1, MPI_INT, 
	       inK,  1, MPI_INT, 
	       MPI_COMM_WORLD);

  /* count totals on each process */
  int *  newKprocs = BuildIntVector(nprocs);
  MPI_Allreduce(outK, newKprocs, nprocs, MPI_INT, MPI_SUM, MPI_COMM_WORLD);

  int totalinK = 0;
  for(p=0;p<nprocs;++p){
    totalinK += inK[p];
  }

  int **newEToV = BuildIntMatrix(totalinK, Nverts);
  double **newVX   = BuildMatrix(totalinK, Nverts);
  double **newVY   = BuildMatrix(totalinK, Nverts);
  double **newVZ   = BuildMatrix(totalinK, Nverts);
  
  int cnt = 0;
  for(p=0;p<nprocs;++p){
    MPI_Irecv(newEToV[cnt], Nverts*inK[p], MPI_INT, p, 666+p, MPI_COMM_WORLD,
	      inrequests+p);
    MPI_Irecv(newVX[cnt], Nverts*inK[p], MPI_DOUBLE, p, 1666+p, MPI_COMM_WORLD,
	      xinrequests+p);
    MPI_Irecv(newVY[cnt], Nverts*inK[p], MPI_DOUBLE, p, 2666+p, MPI_COMM_WORLD,
	      yinrequests+p);
    MPI_Irecv(newVZ[cnt], Nverts*inK[p], MPI_DOUBLE, p, 3666+p, MPI_COMM_WORLD,
	      zinrequests+p);
    cnt = cnt + inK[p];
  }

  for(p=0;p<nprocs;++p){
    int cnt = 0;
    outlist[p]  = BuildIntVector(Nverts*outK[p]);
    xoutlist[p]  = BuildVector(Nverts*outK[p]);
    youtlist[p]  = BuildVector(Nverts*outK[p]);
    zoutlist[p]  = BuildVector(Nverts*outK[p]);

    for(k=0;k<Klocal;++k)
      if(part[k]==p){
	for(v=0;v<Nverts;++v){
	  outlist[p][cnt] = EToV[k][v]; 
	  xoutlist[p][cnt] = VX[k][v];
	  youtlist[p][cnt] = VY[k][v];
	  zoutlist[p][cnt] = VZ[k][v];
	  ++cnt;
	}
      }
    
    MPI_Isend(outlist[p], Nverts*outK[p], MPI_INT, p, 666+procid, MPI_COMM_WORLD, 
	      outrequests+p);
    MPI_Isend(xoutlist[p], Nverts*outK[p], MPI_DOUBLE, p, 1666+procid, MPI_COMM_WORLD, 
	      xoutrequests+p);
    MPI_Isend(youtlist[p], Nverts*outK[p], MPI_DOUBLE, p, 2666+procid, MPI_COMM_WORLD, 
	      youtrequests+p);
    MPI_Isend(zoutlist[p], Nverts*outK[p], MPI_DOUBLE, p, 3666+procid, MPI_COMM_WORLD, 
	      zoutrequests+p);
  }

  MPI_Status *instatus = (MPI_Status*) calloc(nprocs, sizeof(MPI_Status));
  MPI_Status *outstatus = (MPI_Status*) calloc(nprocs, sizeof(MPI_Status));

  MPI_Waitall(nprocs,  inrequests, instatus);
  MPI_Waitall(nprocs, xinrequests, instatus);
  MPI_Waitall(nprocs, yinrequests, instatus);
  MPI_Waitall(nprocs, zinrequests, instatus);

  MPI_Waitall(nprocs,  outrequests, outstatus);
  MPI_Waitall(nprocs, xoutrequests, outstatus);
  MPI_Waitall(nprocs, youtrequests, outstatus);
  MPI_Waitall(nprocs, zoutrequests, outstatus);

  if(mesh->GX!=NULL){
    DestroyMatrix(mesh->GX);
    DestroyMatrix(mesh->GY);
    DestroyMatrix(mesh->GZ);
    DestroyIntMatrix(mesh->EToV);
  }

  mesh->GX = newVX;
  mesh->GY = newVY;
  mesh->GZ = newVZ;
  mesh->EToV = newEToV;
  mesh->K =  totalinK;

  for(p=0;p<nprocs;++p){
    if(outlist[p]){
      free(outlist[p]);
      free(xoutlist[p]);
      free(youtlist[p]);
      free(zoutlist[p]);
    }
  }

  free(outK);
  free(inK);
  
  free(inrequests);
  free(outrequests);

  free(xinrequests);
  free(xoutrequests);
  free(yinrequests);
  free(youtrequests);
  free(zinrequests);
  free(zoutrequests);
  free(instatus);
  free(outstatus);

}
Esempio n. 22
0
void DestroySystem(System *a)
{
  DestroyMatrix(a->Position);
  DestroyMatrix(a->Velocity);
  DestroyMatrix(a->Velocity_xsph);
  DestroyMatrix(a->Velocity_min);
  DestroyMatrix(a->dvdt);
  DestroyMatrix(a->av);
  DestroyMatrix(a->dwdx);
  DestroyMatrix(a->dwdx_r);
  DestroyMatrix(a->dummyVelocity);
  DestroyMatrix(a->dummyAcceleration);
  DestroyMatrix(a->fluctuation);
  DestroyMatrix(a->temps);
  DestroyMatrix(a->DistanceNeighbors);
  DestroyMatrix((double **)a->Neighbors);
  
  free(a->Energy);
  free(a->hsml);
  free(a->Pressure);
  free(a->itype);
  free(a->rho);
  free(a->rho_min);
  free(a->drhodt);  
  free(a->mass);
  free(a->i_pair);
  free(a->j_pair);
  free(a->rij2);
  free(a->w);
  free(a->w_r);
  free(a->i_inflow);
  free(a->gradVxx);
  free(a->gradVxy);
  free(a->gradVyx);
  free(a->gradVyy);
  free(a->strainRatexx);
  free(a->strainRatexy);
  free(a->strainRateyx);
  free(a->strainRateyy);
  free(a->deviatoricxx);
  free(a->deviatoricxy);
  free(a->deviatoricyx);
  free(a->deviatoricyy);
  free(a->divV);
  free(a->KinVisc);
  free(a->numberDensity);
  free(a->dummyPressure);
  free(a->vorticity);
  free(a);
  cleanup();
  
}