/*! \fn getAnalyticalJacobian
 *
 *  function calculates analytical jacobian
 *
 *  \param [ref] [data]
 *  \param [in]  [sysNumber]
 *
 *  \author wbraun
 *
 */
int getAnalyticalJacobianUmfPack(DATA* data, int sysNumber)
{
    int i,ii,j,k,l;
    LINEAR_SYSTEM_DATA* systemData = &(((DATA*)data)->simulationInfo.linearSystemData[sysNumber]);

    const int index = systemData->jacobianIndex;
    int nth = 0;
    int nnz = data->simulationInfo.analyticJacobians[index].sparsePattern.numberOfNoneZeros;

    for(i=0; i < data->simulationInfo.analyticJacobians[index].sizeRows; i++)
    {
        data->simulationInfo.analyticJacobians[index].seedVars[i] = 1;

        ((systemData->analyticalJacobianColumn))(data);

        for(j = 0; j < data->simulationInfo.analyticJacobians[index].sizeCols; j++)
        {
            if(data->simulationInfo.analyticJacobians[index].seedVars[j] == 1)
            {
                if(j==0)
                    ii = 0;
                else
                    ii = data->simulationInfo.analyticJacobians[index].sparsePattern.leadindex[j-1];
                while(ii < data->simulationInfo.analyticJacobians[index].sparsePattern.leadindex[j])
                {
                    l  = data->simulationInfo.analyticJacobians[index].sparsePattern.index[ii];
                    /* infoStreamPrint(LOG_LS_V, 0, "set on Matrix A (%d, %d)(%d) = %f", i, l, nth, -data->simulationInfo.analyticJacobians[index].resultVars[l]); */
                    systemData->setAElement(i, l, -data->simulationInfo.analyticJacobians[index].resultVars[l], nth, (void*) systemData);
                    nth++;
                    ii++;
                };
            }
        };

        /* de-activate seed variable for the corresponding color */
        data->simulationInfo.analyticJacobians[index].seedVars[i] = 0;
    }

    return 0;
}