/* ----------------------------------------------------------------- * Programmer: Radu Serban @ LLNL * ----------------------------------------------------------------- * SUNDIALS Copyright Start * Copyright (c) 2002-2024, Lawrence Livermore National Security * and Southern Methodist University. * All rights reserved. * * See the top-level LICENSE and NOTICE files for details. * * SPDX-License-Identifier: BSD-3-Clause * SUNDIALS Copyright End * ----------------------------------------------------------------- * This header file contains definitions and declarations for use by * generic direct linear solvers for Ax = b. It defines types for * dense and banded matrices and corresponding accessor macros. * -----------------------------------------------------------------*/ #ifndef _SUNDIALS_DIRECT_H #define _SUNDIALS_DIRECT_H #include #include #ifdef __cplusplus /* wrapper to enable C++ usage */ extern "C" { #endif /* * ================================================================= * C O N S T A N T S * ================================================================= */ /* * SUNDIALS_DENSE: dense matrix * SUNDIALS_BAND: banded matrix */ #define SUNDIALS_DENSE 1 #define SUNDIALS_BAND 2 /* * ================================================================== * Type definitions * ================================================================== */ /* * ----------------------------------------------------------------- * Type : SUNDlsMat * ----------------------------------------------------------------- * The type SUNDlsMat is defined to be a pointer to a structure * with various sizes, a data field, and an array of pointers to * the columns which defines a dense or band matrix for use in * direct linear solvers. The M and N fields indicates the number * of rows and columns, respectively. The data field is a one * dimensional array used for component storage. The cols field * stores the pointers in data for the beginning of each column. * ----------------------------------------------------------------- * For DENSE matrices, the relevant fields in SUNDlsMat are: * type = SUNDIALS_DENSE * M - number of rows * N - number of columns * ldim - leading dimension (ldim >= M) * data - pointer to a contiguous block of sunrealtype variables * ldata - length of the data array =ldim*N * cols - array of pointers. cols[j] points to the first element * of the j-th column of the matrix in the array data. * * The elements of a dense matrix are stored columnwise (i.e. columns * are stored one on top of the other in memory). * If A is of type SUNDlsMat, then the (i,j)th element of A (with * 0 <= i < M and 0 <= j < N) is given by (A->data)[j*n+i]. * * The SUNDLS_DENSE_COL and SUNDLS_DENSE_ELEM macros below allow a * user to access efficiently individual matrix elements without * writing out explicit data structure references and without knowing * too much about the underlying element storage. The only storage * assumption needed is that elements are stored columnwise and that a * pointer to the jth column of elements can be obtained via the * SUNDLS_DENSE_COL macro. * ----------------------------------------------------------------- * For BAND matrices, the relevant fields in SUNDlsMat are: * type = SUNDIALS_BAND * M - number of rows * N - number of columns * mu - upper bandwidth, 0 <= mu <= min(M,N) * ml - lower bandwidth, 0 <= ml <= min(M,N) * s_mu - storage upper bandwidth, mu <= s_mu <= N-1. * The dgbtrf routine writes the LU factors into the storage * for A. The upper triangular factor U, however, may have * an upper bandwidth as big as MIN(N-1,mu+ml) because of * partial pivoting. The s_mu field holds the upper * bandwidth allocated for A. * ldim - leading dimension (ldim >= s_mu) * data - pointer to a contiguous block of sunrealtype variables * ldata - length of the data array =ldim*(s_mu+ml+1) * cols - array of pointers. cols[j] points to the first element * of the j-th column of the matrix in the array data. * * The SUNDLS_BAND_COL, SUNDLS_BAND_COL_ELEM, and SUNDLS_BAND_ELEM * macros below allow a user to access individual matrix elements * without writing out explicit data structure references and without * knowing too much about the underlying element storage. The only * storage assumption needed is that elements are stored columnwise * and that a pointer into the jth column of elements can be obtained * via the SUNDLS_BAND_COL macro. The SUNDLS_BAND_COL_ELEM macro * selects an element from a column which has already been isolated * via SUNDLS_BAND_COL. The macro SUNDLS_BAND_COL_ELEM allows the user * to avoid the translation from the matrix location (i,j) to the * index in the array returned by SUNDLS_BAND_COL at which the (i,j)th * element is stored. * ----------------------------------------------------------------- */ typedef struct _DlsMat { int type; sunindextype M; sunindextype N; sunindextype ldim; sunindextype mu; sunindextype ml; sunindextype s_mu; sunrealtype* data; sunindextype ldata; sunrealtype** cols; }* SUNDlsMat; /* * ================================================================== * Data accessor macros * ================================================================== */ /* * ----------------------------------------------------------------- * SUNDLS_DENSE_COL and SUNDLS_DENSE_ELEM * ----------------------------------------------------------------- * * SUNDLS_DENSE_COL(A,j) references the jth column of the M-by-N dense * matrix A, 0 <= j < N. The type of the expression SUNDLS_DENSE_COL(A,j) * is (sunrealtype *). After the assignment col_j = SUNDLS_DENSE_COL(A,j), * col_j may be treated as an array indexed from 0 to M-1. The (i,j)-th * element of A is thus referenced by * col_j[i]. * * SUNDLS_DENSE_ELEM(A,i,j) references the (i,j)th element of the dense * M-by-N matrix A, 0 <= i < M ; 0 <= j < N. * * ----------------------------------------------------------------- */ #define SUNDLS_DENSE_COL(A, j) ((A->cols)[j]) #define SUNDLS_DENSE_ELEM(A, i, j) ((A->cols)[j][i]) /* * ----------------------------------------------------------------- * SUNDLS_BAND_COL, SUNDLS_BAND_COL_ELEM, and SUNDLS_BAND_ELEM * ----------------------------------------------------------------- * * SUNDLS_BAND_COL(A,j) references the diagonal element of the jth * column of the N by N band matrix A, 0 <= j <= N-1. The type of the * expression SUNDLS_BAND_COL(A,j) is sunrealtype *. The pointer returned * by the call SUNDLS_BAND_COL(A,j) can be treated as an array which * is indexed from -(A->mu) to (A->ml). * * SUNDLS_BAND_COL_ELEM references the (i,j)th entry of the band * matrix A when used in conjunction with SUNDLS_BAND_COL. The index * (i,j) should satisfy j-(A->mu) <= i <= j+(A->ml). * * SUNDLS_BAND_ELEM(A,i,j) references the (i,j)th element of the * M-by-N band matrix A, where 0 <= i,j <= N-1. The location (i,j) * should further satisfy j-(A->mu) <= i <= j+(A->ml). * * ----------------------------------------------------------------- */ #define SUNDLS_BAND_COL(A, j) (((A->cols)[j]) + (A->s_mu)) #define SUNDLS_BAND_COL_ELEM(col_j, i, j) (col_j[(i) - (j)]) #define SUNDLS_BAND_ELEM(A, i, j) ((A->cols)[j][(i) - (j) + (A->s_mu)]) /* * ================================================================== * Exported function prototypes (functions working on SUNDlsMat) * ================================================================== */ /* * ----------------------------------------------------------------- * Function: SUNDlsMat_NewDenseMat * ----------------------------------------------------------------- * SUNDlsMat_NewDenseMat allocates memory for an M-by-N dense matrix * and returns the storage allocated (type SUNDlsMat). * SUNDlsMat_NewDenseMat returns NULL if the request for matrix * storage cannot be satisfied. See the above documentation for the * type SUNDlsMat for matrix storage details. * ----------------------------------------------------------------- */ SUNDIALS_EXPORT SUNDlsMat SUNDlsMat_NewDenseMat(sunindextype M, sunindextype N); /* * ----------------------------------------------------------------- * Function: SUNDlsMat_NewBandMat * ----------------------------------------------------------------- * SUNDlsMat_NewBandMat allocates memory for an M-by-N band matrix * with upper bandwidth mu, lower bandwidth ml, and storage upper * bandwidth smu. Pass smu as follows depending on whether A will be * LU factored: * * (1) Pass smu = mu if A will not be factored. * * (2) Pass smu = MIN(N-1,mu+ml) if A will be factored. * * SUNDlsMat_NewBandMat returns the storage allocated (type SUNDlsMat) * or NULL if the request for matrix storage cannot be satisfied. See * the documentation for the type SUNDlsMat for matrix storage * details. * ----------------------------------------------------------------- */ SUNDIALS_EXPORT SUNDlsMat SUNDlsMat_NewBandMat(sunindextype N, sunindextype mu, sunindextype ml, sunindextype smu); /* * ----------------------------------------------------------------- * Functions: SUNDlsMat_DestroyMat * ----------------------------------------------------------------- * SUNDlsMat_DestroyMat frees the memory allocated by * SUNDlsMat_NewDenseMat or SUNDlsMat_NewBandMat * ----------------------------------------------------------------- */ SUNDIALS_EXPORT void SUNDlsMat_DestroyMat(SUNDlsMat A); /* * ----------------------------------------------------------------- * Function: SUNDlsMat_NewIntArray * ----------------------------------------------------------------- * SUNDlsMat_NewIntArray allocates memory an array of N int's and * returns the pointer to the memory it allocates. If the request for * memory storage cannot be satisfied, it returns NULL. * ----------------------------------------------------------------- */ SUNDIALS_EXPORT int* SUNDlsMat_NewIntArray(int N); /* * ----------------------------------------------------------------- * Function: SUNDlsMat_NewIndexArray * ----------------------------------------------------------------- * SUNDlsMat_NewIndexArray allocates memory an array of N * sunindextype's and returns the pointer to the memory it * allocates. If the request for memory storage cannot be satisfied, * it returns NULL. * ----------------------------------------------------------------- */ SUNDIALS_EXPORT sunindextype* SUNDlsMat_NewIndexArray(sunindextype N); /* * ----------------------------------------------------------------- * Function: SUNDlsMat_NewRealArray * ----------------------------------------------------------------- * SUNDlsMat_NewRealArray allocates memory an array of N sunrealtype and * returns the pointer to the memory it allocates. If the request for * memory storage cannot be satisfied, it returns NULL. * ----------------------------------------------------------------- */ SUNDIALS_EXPORT sunrealtype* SUNDlsMat_NewRealArray(sunindextype N); /* * ----------------------------------------------------------------- * Function: SUNDlsMat_DestroyArray * ----------------------------------------------------------------- * SUNDlsMat_DestroyArray frees memory allocated by * SUNDlsMat_NewIntArray, SUNDlsMat_NewIndexArray, or * SUNDlsMat_NewRealArray. * ----------------------------------------------------------------- */ SUNDIALS_EXPORT void SUNDlsMat_DestroyArray(void* p); /* * ----------------------------------------------------------------- * Function : SUNDlsMat_AddIdentity * ----------------------------------------------------------------- * SUNDlsMat_AddIdentity adds 1.0 to the main diagonal (A_ii, * i=0,1,...,N-1) of the M-by-N matrix A (M>= N) and stores the result * back in A. SUNDlsMat_AddIdentity is typically used with square * matrices. SUNDlsMat_AddIdentity does not check for M >= N and * therefore a segmentation fault will occur if M < N! * ----------------------------------------------------------------- */ SUNDIALS_EXPORT void SUNDlsMat_AddIdentity(SUNDlsMat A); /* * ----------------------------------------------------------------- * Function : SUNDlsMat_SetToZero * ----------------------------------------------------------------- * SUNDlsMat_SetToZero sets all the elements of the M-by-N matrix A * to 0.0. * ----------------------------------------------------------------- */ SUNDIALS_EXPORT void SUNDlsMat_SetToZero(SUNDlsMat A); /* * ----------------------------------------------------------------- * Functions: SUNDlsMat_PrintMat * ----------------------------------------------------------------- * This function prints the M-by-N (dense or band) matrix A to * outfile as it would normally appear on paper. * It is intended as debugging tools with small values of M and N. * The elements are printed using the %g/%lg/%Lg option. * A blank line is printed before and after the matrix. * ----------------------------------------------------------------- */ SUNDIALS_EXPORT void SUNDlsMat_PrintMat(SUNDlsMat A, FILE* outfile); /* * ================================================================== * Exported function prototypes (functions working on sunrealtype**) * ================================================================== */ SUNDIALS_EXPORT sunrealtype** SUNDlsMat_newDenseMat(sunindextype m, sunindextype n); SUNDIALS_EXPORT sunrealtype** SUNDlsMat_newBandMat(sunindextype n, sunindextype smu, sunindextype ml); SUNDIALS_EXPORT void SUNDlsMat_destroyMat(sunrealtype** a); SUNDIALS_EXPORT int* SUNDlsMat_newIntArray(int n); SUNDIALS_EXPORT sunindextype* SUNDlsMat_newIndexArray(sunindextype n); SUNDIALS_EXPORT sunrealtype* SUNDlsMat_newRealArray(sunindextype m); SUNDIALS_EXPORT void SUNDlsMat_destroyArray(void* v); #ifdef __cplusplus } #endif #endif